CREATE FUNCTION(外部标量)语句

CREATE FUNCTION (External Scalar) 语句用于在当前服务器上注册用户定义的外部标量函数。 标量函数 每次调用时都会返回单个值,并且通常在 SQL 表达式有效的情况下有效。

调用

此语句可以嵌入在应用程序中,也可通过动态 SQL 语句来发出。 它是一个可执行语句,仅当 DYNAMICRULES 运行行为对于程序包有效时才能动态编译 (SQLSTATE 42509)。

授权

语句授权标识所拥有的特权必须至少包括下列其中一项权限:
  • 数据库上的 IMPLICIT_SCHEMA 权限 (如果函数的隐式或显式模式名不存在)。
  • CREATEIN 对模式的特权 (如果函数的模式名引用现有模式)。
  • 对模式的 SCHEMAADM 权限 (如果函数的模式名称引用现有模式)。
  • DBADM 权限。
语句的授权标识所拥有的特权还必须包含下列其中一个权限:
  • CREATE_EXTERNAL_ROUTINE 对数据库的权限。
  • SYSADM 权限。
  • DBADM 权限 (如果设置了 DB2_ALTERNATE_AUTHZ_BEHAVIOUR 注册表变量并包含值 EXTERNAL_ROUTINE_DBADM)。
要创建非受防护函数,语句的授权标识所拥有的特权还必须至少包含下列其中一个权限 (不适用于 OLE DB 外部表函数或方法):
  • CREATE_NOT_FENCED_ROUTINE 对数据库的权限。
  • SYSADM 权限。
  • DBADM 权限 (如果设置了 DB2_ALTERNATE_AUTHZ_BEHAVIOUR 注册表变量并包含值 NOT_FENCED_ROUTINE_DBADM)
    注: Db2 11.5.8 安全特殊构建 29133 包含对 SYSADM 和 DBADM 权限的隐式权限的更改。 缺省情况下, SYSADM 权限 (而不是 DBADM 权限) 隐式具有 CREATE_EXTERNAL_ROUTINE 和 CREATE_NOT_FENCED_ROUTINE 权限。 如果设置了 DB2_ALTERNATE_AUTHZ_BEHAVIOUR 注册表变量并包含 EXTERNAL_ROUTINE_DBADM 或 NOT_FENCED_ROUTINE_DBADM 值,那么 DBADM 权限也隐式具有这些特权。

语法

Read syntax diagramSkip visual syntax diagramCREATEOR REPLACE FUNCTIONfunction-name( ,parameter-declaration )RETURNS data-type2AS LOCATORdata-type3CAST FROMdata-type4AS LOCATOR option-list
parameter-declaration
Read syntax diagramSkip visual syntax diagram INOUT1INOUTparameter-name data-type1 default-clause AS LOCATOR
data-type1, data-type2, data-type3, data-type4
Read syntax diagramSkip visual syntax diagrambuilt-in-typedistinct-type-namestructured-type-nameREF(type-name)
built-in-type
Read syntax diagramSkip visual syntax diagramSMALLINTINTEGERINTBIGINTDECIMALDECNUMERICNUM(5,0)( integer,0, integer)FLOAT(53)( integer)REALDOUBLEPRECISIONCHARACTERCHAR(1)( integerOCTETSCODEUNITS32)VARCHARCHARACTERCHARVARYING( integerOCTETSCODEUNITS32)FOR BIT DATA2CLOBCHARACTERCHARLARGE OBJECT(1M)( integerKMGOCTETSCODEUNITS32)GRAPHIC(1)( integerCODEUNITS16CODEUNITS32)VARGRAPHIC( integerCODEUNITS16CODEUNITS32)DBCLOB(1M)( integerKMGCODEUNITS16CODEUNITS32)NCHARNATIONALCHARCHARACTER(1)( integer)NVARCHARNCHAR VARYINGNATIONALCHARCHARACTERVARYING( integer)NCLOBNCHAR LARGE OBJECTNATIONAL CHARACTER LARGE OBJECT(1M)( integerKMG)BINARY(1)( integer)VARBINARYBINARY VARYING(integer)BLOBBINARY LARGE OBJECT(1M)( integerKMG)DATETIMETIMESTAMP(6)(integer)XMLSYSPROC.DB2SECURITYLABEL34
default-clause
Read syntax diagramSkip visual syntax diagramDEFAULT NULLconstantspecial-registerglobal-variable(expression)
option-list
Read syntax diagramSkip visual syntax diagramLANGUAGE CJAVACLROLECPPPYTHON5 SPECIFICspecific-nameEXTERNAL NAME'string'identifier PARAMETER STYLE DB2GENERALJAVASQLNPSGENERIC PARAMETER CCSIDASCIIUNICODENOT DETERMINISTICDETERMINISTICFENCEDFENCEDTHREADSAFENOT THREADSAFENOT FENCEDTHREADSAFERETURNS NULL ON NULL INPUTCALLED ON NULL INPUTREADS SQL DATANO SQLCONTAINS SQLSTATIC DISPATCHEXTERNAL ACTIONNO EXTERNAL ACTIONNO SCRATCHPADSCRATCHPAD100lengthNO FINAL CALLFINAL CALLALLOW PARALLELDISALLOW PARALLELNO DBINFODBINFOTRANSFORM GROUPgroup-namePREDICATES(predicate-specification)INHERIT SPECIAL REGISTERSNOT SECUREDSECUREDSTAY RESIDENT NO
predicate-specification
Read syntax diagramSkip visual syntax diagramWHEN  =   <>  <   >   <=  >=  constantEXPRESSION ASexpression-name data-filterindex-exploitationindex-exploitationdata-filter
data-filter
Read syntax diagramSkip visual syntax diagramFILTER USING function-invocationcase-expression
index-exploitation
Read syntax diagramSkip visual syntax diagramSEARCH BY EXACT INDEX EXTENSIONindex-extension-nameexploitation-rule
exploitation-rule
Read syntax diagramSkip visual syntax diagramWHEN KEY(parameter-name1 )USEsearch-method-name( ,parameter-name2 )
Notes:
  • 1 OUT and INOUT are valid only if the function has LANGUAGE C.
  • 2 The FOR BIT DATA clause can be specified in any order with the other column constraints that follow. The FOR BIT DATA clause cannot be specified with string units CODEUNITS32 (SQLSTATE 42613).
  • 3 DB2SECURITYLABEL is the built-in distinct type that must be used to define the row security label column of a protected table.
  • 4 For a column of type DB2SECURITYLABEL, NOT NULL WITH DEFAULT is implicit and cannot be explicitly specified (SQLSTATE 42842). The default value for a column of type DB2SECURITYLABEL is the session authorization ID's security label for write access.
  • 5 LANGUAGE SQL is also supported.

描述

OR REPLACE
指定替换当前服务器上存在的函数的定义。 在目录中替换新定义之前,现有定义将被有效删除,但授予函数的权限不受影响。 此选项只能由对象所有者指定。 如果函数的定义在当前服务器上不存在,那么忽略此选项。 要替换现有函数,新定义的特定名称和函数名必须与旧定义的特定名称和函数名相同,或者新定义的签名必须与旧定义的签名相匹配。 否则,将创建新函数。

如果在行许可权或列掩码的定义中引用了该函数,那么无法替换该函数 (SQLSTATE 42893)。

函数名
命名要定义的函数。 它是指定函数的限定名称或非限定名称。 function-name 的非限定形式为 SQL 标识。 在动态 SQL 语句中,使用 CURRENT SCHEMA 专用寄存器作为未限定的对象名的限定符。 在静态 SQL 语句中,QUALIFIER 预编译/绑定选项隐式地指定未限定的对象名的限定符。 限定格式为 schema-name 后跟句点和 SQL 标识。 如果第一个参数是结构化类型,那么限定名不得与第一个参数的数据类型相同。

名称 (包括隐式或显式限定符) 以及参数数量和每个参数的数据类型 (不考虑数据类型的任何长度,精度或小数位属性) 不得标识目录中描述的函数或方法 (SQLSTATE 42723)。 未限定的名称以及参数的数量和数据类型虽然在其模式中是唯一的,但不需要在模式之间是唯一的。

如果指定了两部分名称,那么 schema-name 不能以 SYS开头; 否则,将产生错误 (SQLSTATE 42939)。

在谓词中用作关键字的多个名称保留供系统使用,并且不能用作 function-name。 名称包含 SOME、ANY、ALL、NOT、AND、OR、BETWEEN、NULL、LIKE、EXISTS、IN、UNIQUE、OVERLAPS、SIMILAR、MATCH 和比较运算符。 未能遵守此规则将导致错误 (SQLSTATE 42939)。

一般情况下,如果函数的签名存在一些差异,那么可以将相同的名称用于多个函数。

虽然没有禁止它,但是外部用户定义的函数不应该被赋予与内置函数相同的名称,除非它是有意覆盖。 要为具有不同含义的函数提供相同的名称 (例如, LENGTH , VALUE , MAX) ,并使用一致的自变量作为内置标量或聚集函数,请为动态 SQL 语句带来麻烦,或者在静态 SQL 应用程序重新绑定时; 应用程序可能失败,或者可能更糟糕的是,可能在提供不同结果的同时成功运行。

(parameter-declaration,...)
标识函数的输入参数个数,并指定每个参数的模式、名称、数据类型和可选的缺省值。 必须为该函数期望接收的每个参数指定列表中的一个条目。 最多可指定 90 个参数 (SQLSTATE 54023)。
你可以注册一个没有参数的函数;仍然需要括号,并且没有干预数据类型。 例如:
   CREATE FUNCTION WOOFER() ...

对于所有相应的参数,不允许模式中的两个名称完全相同的函数具有完全相同的类型。 此类型比较中不考虑长度、精度和比例。 因此,CHAR(8) 和 CHAR(35) 被认为是同一类型,DECIMAL (11,2) 和 DECIMAL (4,3) 也被认为是同一类型。 为参数指定的弱类型单值类型被视为与单值类型的源类型相同的数据类型。 对于 Unicode 数据库,CHAR(13) 和 GRAPHIC (8) 被认为是同一类型。 还有一些类型的进一步捆绑会导致将它们视为用于此目的的相同类型,例如 DECIMAL 和 NUMERIC。 重复签名返回错误 (SQLSTATE 42723)。

| | 进出
指定参数的模式。 如果函数返回错误,那么未定义 OUT 参数,并且 INOUT 参数保持不变。 缺省值为 IN。
IN
将参数标识为函数的输入参数。 返回控制时,对函数中的参数所作的任何更改都不可用于调用上下文。
OUT
将参数标识为函数的输出参数。
必须使用 LANGUAGE C 定义函数 (SQLSTATE 42613)。
只能在复合 SQL (编译型) 语句中的赋值语句的右侧引用该函数,并且该函数引用不能是表达式的一部分 (SQLSTATE 42887)。
INOUT
将参数标识为函数的输入和输出参数。
必须使用 LANGUAGE C 定义函数 (SQLSTATE 42613)。
只能在复合 SQL (编译型) 语句中的赋值语句的右侧引用该函数,并且该函数引用不能是表达式的一部分 (SQLSTATE 42887)。
参数名
指定参数的可选名称。 需要参数名称才能在谓词规范的 index-起来利用 子句中引用函数的参数。 该名称不能与参数列表中的任何其他 parameter-name 相同 (SQLSTATE 42734)。
data-type1
指定参数的数据类型。 数据类型可以是内置数据类型,单值类型,结构化类型或引用类型。 有关每种内置数据类型的更完整描述,请参阅 CREATE TABLE。 某些数据类型并非在所有语言中都受支持。 有关 SQL 数据类型与主语言数据类型之间的映射的详细信息,请参阅 映射到嵌入式 SQL 应用程序中的 SQL 数据类型的数据类型
  • 日期时间类型参数作为字符数据类型传递,数据以 ISO 格式传递。
  • DECIMAL (和 NUMERIC) 对于 LANGUAGE C 和 OLE 无效 (SQLSTATE 42815)。
  • DECFLOAT 在 LANGUAGE C、 COBOL、CLR、JAVA 和 OLE 环境下无效(SQLSTATE 42815)。
  • XML 不适用于 LANGUAGE OLE。
  • 因为在函数中看到的 XML 值是作为函数调用中的参数传递的 XML 值的序列化版本,所以必须使用语法 XML AS CLOB(n)来声明类型为 XML 的参数。
  • CLR 不支持大于 28 的 DECIMAL 小数位 (SQLSTATE 42613)。
  • 不能指定数组类型 (SQLSTATE 42815)。
  • BINARY 和 VARBINARY 数据类型不适用于 LANGUAGE CLR 和 OLE (SQLSTATE 42815)。
对于用户定义的单值类型,参数的长度,精度或小数位属性是单值类型的源类型 (在 CREATE TYPE 上指定) 的那些属性。 将单值类型参数作为单值类型的源类型传递。 如果未限定单值类型的名称,那么数据库管理器将通过在 SQL 路径中搜索模式来解析模式名称。

对于用户定义的结构化类型,相应的变换函数必须存在于关联的变换组中。

对于引用类型,如果参数未限定作用域,那么可以将参数指定为 REF (type-name)。

缺省值
指定参数的缺省值。 缺省值可以是常量,专用寄存器,全局变量,表达式或关键字 NULL。 可以指定为缺省值的专用寄存器与可以为列缺省值指定的专用寄存器相同 (请参阅 CREATE TABLE 语句中的 default-clause )。 通过使用表达式,可以指定其他专用寄存器作为缺省值。

该表达式可以是 Expressions 中描述的类型的任何表达式。 如果未指定缺省值,那么该参数没有缺省值,并且调用该过程时不得省略相应的自变量。 表达式 的最大大小为 64K 字节。

缺省表达式不得修改 SQL 数据(SQLSTATE 428FL 或 SQLSTATE 429BL)。 该表达式必须与参数数据类型赋值兼容 (SQLSTATE 42821)。

在下列情况下,不得指定缺省值:
  • 对于 INOUT 或 OUT 参数 (SQLSTATE 42601)
  • 对于 ARRAY、ROW 或 CURSOR 类型的参数 (SQLSTATE 429BB)
  • 对于还指定了 PREDICATES 子句的函数定义的参数 (SQLSTATE 42613)
AS LOCATOR
指定将参数值的定位器传递到函数而不是实际值。 仅对具有 LOB 数据类型或基于 LOB 数据类型的单值类型的参数指定 AS LOCATOR (SQLSTATE 42601)。 传递定位器而不是值可能会导致传递到函数的字节数减少,尤其是当参数的值非常大时。

AS LOCATOR 子句对确定数据类型是否可以提升没有影响,也不影响函数解析中使用的函数特征符。

如果函数是 FENCED 并且具有 NO SQL 选项,那么不能指定 AS LOCATOR 子句 (SQLSTATE 42613)。

退货
此必需子句标识函数的输出。
data-type2
指定输出的数据类型。

在这种情况下,适用于函数参数的注意事项与先前在 data-type1 中描述的外部函数参数的注意事项完全相同。

AS LOCATOR
对于 LOB 类型或基于 LOB 类型的单值类型,可以添加 AS LOCATOR 子句。 这指示将从 UDF 而不是实际值传递 LOB 定位器。
data-type3 CAST FROM data-type4
指定输出的数据类型。

这种形式的 RETURNS 子句用于向调用语句返回与函数代码返回的数据类型不同的数据类型。 例如,在

   CREATE FUNCTION GET_HIRE_DATE(CHAR(6))
     RETURNS DATE CAST FROM CHAR(10)
     ...

函数代码将 CHAR (10) 值返回给数据库管理器,而数据库管理器又将其转换为 DATE 并将该值传递给调用语句。 data-type4 必须可强制转型为 data-type3 参数。 如果不可级联,那么会产生错误 (SQLSTATE 42880)。

由于可以从 data-type4, 推断 data-type3 的长度,精度或小数位,因此不需要 (但仍允许) 指定为 data-type3指定的参数化类型的长度,精度或小数位。 可以改为使用空括号 (例如,可以使用 VARCHAR ())。 不能使用 FLOAT() ( SQLSTATE 42601),因为参数值指示不同的数据类型(REAL 或 DOUBLE)。

单值类型,数组类型 和结构化类型作为 data-type4 中指定的类型无效 (SQLSTATE 42815)。

强制类型转换操作还需要执行可能导致发生转换错误的运行时检查。

AS LOCATOR
对于基于 LOB 类型的 LOB 类型或单值类型的 data-type4 规范,可以添加 AS LOCATOR 子句。 这指示 LOB 定位器将从 UDF (而不是实际值) 传回。
built-in-type
请参阅 CREATE TABLE 以获取内置数据类型的描述。
特定 特定名称
为要定义的函数实例提供唯一名称。 对此函数执行 source、删除或注释时,可以使用此特定名称。 它不能用来调用函数。 非限定格式的 specific-name 是 SQL 标识。 限定格式为 schema-name 后跟句点和 SQL 标识。 该名称 (包括隐式或显式限定符) 不得标识应用程序服务器上存在的其他函数实例或方法规范; 否则将产生错误 (SQLSTATE 42710)。

specific-name 可能与现有 function-name相同。

如果未指定限定符,那么将使用用于 function-name 的限定符。 如果指定了限定符,那么它必须与 function-name 的显式或隐式限定符相同,否则将发生错误 (SQLSTATE 42882)。

如果未指定 specific-name,那么数据库管理器会生成唯一名称。 唯一名称是 SQL 后跟字符时间戳记,即 SQLyymmddhhmmssxxx。

EXTERNAL
此子句指示正在使用 CREATE FUNCTION 语句根据以外部编程语言编写的代码并遵循记录的链接约定和接口来注册新的函数。

如果未指定 NAME 子句 NAME function-name

NAME "string"
此子句标识实现所定义函数的用户编写代码的名称。

"string" 选项是最大长度为 254 个字节的字符串常量。 此字符串所用的格式取决于指定的 LANGUAGE。

  • 对于 LANGUAGE C:

    指定的 string 是库中的库名和函数,数据库管理器调用该库来执行正在创建的用户定义的函数。 执行 CREATE FUNCTION 语句时,库 (以及库中的函数) 不需要存在。 但是,在 SQL 语句中使用该函数时,该库中的库和函数必须存在并且可从数据库服务器访问; 否则,将返回错误 (SQLSTATE 42724)。

    可以按如下所示指定 string :
    Read syntax diagramSkip visual syntax diagram ' library_idabsolute_path_id !func_id '

    单引号内不允许有多余的空格。

    库标识
    标识包含函数的库名。 数据库管理器会查找该库,如下所示:
    操作系统 库名位置

    Linux®
    AIX®

    如果 myfunc 作为 library_id提供,并且正在从 /u/production运行数据库管理器,那么数据库管理器将在库 /u/production/sqllib/function/myfunc 中查找函数
    Windows 数据库管理器将在 LIBPATH 或 PATH 环境变量指定的目录路径中查找函数
    绝对路径标识
    标识包含函数的文件的完整路径名。 格式视操作系统而定,如下表所示:
    操作系统 完整路径名示例

    Linux
    AIX

    值 "/u/jchui/mylib/myfunc" 将导致数据库管理器在 /u/jchui/mylib 中查找 myfunc 共享库。
    Windows 值 "d:\mylib\myfunc.dll" 将导致数据库管理器从 d:\mylib 目录装入动态链接库 myfunc.dll。 如果使用绝对路径标识来识别例程主体,请务必追加 .dll 扩展名。
    ! func_id
    标识要调用的函数的入口点名称。 我的! 用作库标识与函数标识之间的定界符。 格式视操作系统而定,如下表所示:
    操作系统 函数的入口点名称

    Linux
    AIX

    值 "mymod!func8" 将指示数据库管理器在该库中查找库 $inst_home_dir/sqllib/function/mymod 并使用入口点 func8
    Windows 值 "mymod!func8" 将指示数据库管理器装入 mymod.dll 文件并在动态链接库 (DLL) 中调用 func8() 函数。

    如果未正确编排该字符串的格式,那么会返回错误 (SQLSTATE 42878)。

    每个外部函数的主体应该位于每个数据库分区上可用的目录中。

  • 对于 LANGUAGE JAVA:

    指定的 string 包含可选的 JAR 文件标识,类标识和方法标识,数据库管理器将调用这些标识来执行要创建的用户定义的函数。 执行 CREATE FUNCTION 语句时,不需要存在类标识和方法标识。 如果指定了 jar_id ,那么在执行 CREATE FUNCTION 语句时它必须存在。 但是,在 SQL 语句中使用该函数时,方法标识必须存在并且可从数据库服务器访问; 否则,将返回错误 (SQLSTATE 42724)。

    可以按如下所示指定 string :

    Read syntax diagramSkip visual syntax diagram ' jar_id : class_id .! method_id '

    单引号内不允许有多余的空格。

    jar_id
    识别在数据库中安装 JAR 集合时对其指定的 JAR 标识。 它可以是简单标识,也可以是模式限定标识。 示例包括“myJar”和“mySchema.mmyJar”。
    类标识
    标识 Java™ 对象的类标识。 如果类是软件包的一部分,类标识符部分必须包含完整的软件包前缀,例如'myPacks.UserFuncs'。 Java 虚拟机将在其中查找类的目录取决于操作系统,如下表中所示:
    操作系统 Java 虚拟机将在其中查找类的目录

    Linux
    AIX

    '.../myPacks/UserFuncs/'
    Windows '...\myPacks\UserFuncs\'
    方法ID
    标识要调用的 Java 对象的方法名称。
  • 对于 LANGUAGE CLR:

    指定的 string 表示 .NET 组合件 (库或可执行文件) ,该组合件中的类以及数据库管理器为执行所创建的函数而调用的类中的方法。 执行 CREATE FUNCTION 语句时,模块,类和方法不需要存在。 但是,在 SQL 语句中使用该函数时,模块,类和方法必须存在并且可从数据库服务器访问; 否则,将返回错误 (SQLSTATE 42724)。

    使用“/clr”编译器选项(指出例程包括受管代码扩展)编译的 C++ 例程必须编目为“LANGUAGE CLR”而非“LANGUAGE C”。 数据库服务器需要知道 .NET 基础结构正在用户定义的函数中使用,以便做出必要的运行时决策。 所有使用 .NET 基础结构的用户定义函数都必须编目为 "LANGUAGE CLR"。

    可以按如下所示指定 string :
    Read syntax diagramSkip visual syntax diagram ' assembly : class_id ! method_id '

    名称必须括在单引号中。 不允许有多余的空格。

    组合件
    标识类所在的 DLL 或其他组合件文件。 必须指定任何文件扩展名(例如 .dll)。 如果未提供完整路径名,那么该文件必须位于数据库产品的安装路径的函数目录中

    例如,c:\sqllib\function

    如果该文件位于安装函数目录的子目录中,那么可以在文件名之前提供该子目录,而不是指定完整路径。

    例如,如果安装目录为 c:\sqllib ,而组合件文件为 c:\sqllib\function\myprocs\mydotnet.dll,那么仅需要为组合件指定 "myprocs\mydotnet.dll"。

    此参数是否区分大小写与文件系统相同。

    类标识
    指定给定组合件中的类名,要调用的方法位于该类中。 如果该类驻留在名称空间中,那么除了指定该类之外,还必须提供完整的名称空间。 例如,如果类 EmployeeClass 在名称空间 MyCompany.ProcedureClasses 中,那么必须为该类指定 MyCompany.ProcedureClasses.EmployeeClass。 请注意,某些 .NET 语言的编译器会添加项目名称来作为该类的名称空间,并且根据您是使用命令行编译器还是 GUI 编译器,行为可能有所不同。 此参数区分大小写。
    方法ID
    指定给定的类中所要调用的方法。 此参数区分大小写。
  • 对于 LANGUAGE OLE:

    指定的 string 是 OLE 程序化标识 (进步标识) 或类标识 (clsid) 以及方法标识,数据库管理器将调用此标识来执行正在创建的用户定义的函数。 当执行 CREATE FUNCTION 语句时,程序标识或类标识以及方法标识不需要存在。 但是,在 SQL 语句中使用该函数时,方法标识必须存在并且可从数据库服务器访问; 否则,将返回错误 (SQLSTATE 42724)。

    可以按如下所示指定 string :
    Read syntax diagramSkip visual syntax diagram ' progidclsid ! method_id '

    单引号内不允许有多余的空格。

    进度标识
    识别 OLE 对象的程序化标识。

    进度标识 未由数据库管理器解释,而仅在运行时转发到 OLE API。 指定的 OLE 对象必须是可创建的,并且支持后期绑定 (也称为基于 IDispatch 的绑定)。

    CLSID
    识别所要创建的 OLE 对象的类标识。 在 OLE 对象未向进度标识注册的情况下,可以将其用作指定 进度标识 的替代方法。 clsid 的格式如下:
    {nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn}
    其中,“n”是字母数字字符。 clsid 未由数据库管理器解释,而仅在运行时转发到 OLE API。
    方法ID
    识别所要调用的 OLE 对象的方法名。
  • 对于 LANGUAGE CPP:

    指定的 string 是库中的库标识和类标识,其中包含数据库管理器为执行正在创建的用户定义函数而调用的评估方法。 如果未正确编排该字符串的格式,那么会返回错误 (SQLSTATE 42878)。

    执行 CREATE FUNCTION 语句时,不需要库 (或库中的类) 存在。 但是,在 SQL 语句中使用该函数时,该库中的库和类必须存在并且可从数据库服务器访问; 否则,将返回错误 (SQLSTATE 42724)。

    每个外部函数的主体应该位于每个数据库分区上可用的目录中。

    可以按如下所示指定 string :
    Read syntax diagramSkip visual syntax diagram ' library_idabsolute_path_id ! class_id '
    单引号内不允许有多余的空格。
    库标识
    包含函数的库的名称:
    • 在 UNIX 系统上,如果指定的库标识为 myfunc,并且正在从 /u/production运行数据库管理器,那么数据库管理器将在以下库中查找函数:
      /u/production/sqllib/function/myfunc
    • 在 Windows 操作系统上,数据库管理器在 LIBPATH 或 PATH 环境变量指定的目录路径中查找函数。
    绝对路径标识
    包含函数的文件的完整路径。 例如:
    • 在 UNIX 系统上,以下规范导致数据库管理器在 /u/jchui/mylib 中查找 myfunc 共享库:
      '/u/jchui/mylib/myfunc'
    • 在 Windows 操作系统上,以下规范导致数据库管理器从 d:\mylib 目录装入动态链接库 myfunc.dll :
      'd:\mylib\myfunc.dll'
      如果使用绝对路径标识来标识例程主体,请确保附加 .dll 扩展名。
    类标识
    包含要调用的方法的类的名称。
    例如,如果指定 'mymod!myclass':
    • 在 UNIX 系统上,数据库管理器查找库 $inst_home_dir/sqllib/function/mymod 并在该库中调用 myclass 类的 evaluate 方法。
    • 在 Windows 操作系统上,数据库管理器装入 mymod.dll 文件并在动态链接库 (DLL) 中调用 myclass 类的 evaluate 方法。
NAME 标识
这个指定的 identifier 是 SQL 标识。 该 SQL 标识在字符串中用作 library-id。 除非它是定界标识,否则该标识会转换为大写。 如果使用了模式名称来限定该标识,那么模式名称部分会被忽略。 这种格式的 NAME 只能与 LANGUAGE C 配合使用。
中文
此必需子句指定将用户定义的函数主体写入的语言接口约定。
C
数据库管理器调用用户定义的函数,就像它是 C 函数一样。 用户定义的函数必须符合标准 ANSI C 原型定义的 C 语言调用和链接约定。
JAVA
数据库管理器将用户定义的函数作为 Java 类中的方法进行调用。
CLR
数据库管理器将用户定义的函数作为 .NET 类中的方法进行调用。 LANGUAGE CLR 仅支持在 Windows 操作系统上运行的用户定义函数。 不得对 CLR 例程指定 NOT FENCED (SQLSTATE 42601)。
OLE
数据库管理器调用用户定义的函数,就像它是 OLE 自动化对象公开的方法一样。 用户定义的函数必须符合 OLE 自动化数据类型和调用机制,如 OLE Automation Programmer 's Reference中所述。

仅在 Windows 操作系统中,此数据库产品的用户定义函数支持 LANGUAGE OLE。 不能对使用 LANGUAGE OLE 定义的 UDF 指定 THREADSAFE (SQLSTATE 42613)。

CPP
数据库管理器通过调用 C++ 类的 evaluate 方法来调用用户定义的函数。
python
数据库管理器将用户定义的函数作为 Python 类中的方法进行调用。
PARAMETER STYLE
此子句用于指定用于将参数传递到函数以及从函数返回值的约定。
DB2GENERAL
用于指定用于将参数传递到 Java 类中定义为方法的外部函数并从这些函数返回值的约定。 这只能在使用 LANGUAGE JAVA 时指定。

值 DB2GENRL 可用作 DB2GENERAL的同义词。

JAVA
这意味着该函数将使用符合 Java 语言和 SQLJ 例程规范的参数传递约定。 仅当使用 LANGUAGE JAVA 时才能指定此参数,未将任何结构化数据类型指定为参数,也未将任何 CLOB , BLOB 或 DBCLOB 数据类型指定为返回类型 (SQLSTATE 429B8)。 PARAMETER STYLE JAVA 函数不支持 FINAL CALL , SCRATCHPAD 或 DBINFO 子句。
SQL
用于指定用于将参数传递到符合 C 语言调用和链接约定的外部函数, OLE 自动化对象所公开的方法 或 .NET 对象的公共静态方法的值并从中返回值的约定。 This must be specified when LANGUAGE C, LANGUAGE CLR , or LANGUAGE OLE is used.
通用国家公园

用于指定用于将参数传递到 C++ 类中定义为方法的外部函数以及从这些函数返回值的约定。 仅当 LANGUAGE 选项设置为 CPP 或 PYTHON时,才能指定此选项。

当将 NPSGENERIC 指定为参数样式时,将以 C++ 编写 UDF 作为 nz.udx_ver2.Udf 类。 除了它的构造函数和析构函数之外,该类还必须实现以下两种方法:
静态 Udf* Udf::instantiateUdxInit *pInit)
静态成员方法 instantiate () ,它必须实例化 UDF 派生类的新实例,并将指向新实例的指针作为类 Udf 指针返回。 引擎使用此方法来创建 UDF 对象的实例。
虚拟 ReturnValue Udf: :evaluate ()
成员方法 evaluate () ,由引擎调用以评估用户函数并向调用者返回值。
PARAMETER CCSID
指定要用于传入和传入函数的所有字符串数据的编码方案。 如果未指定 PARAMETER CCSID 子句,那么缺省值为 PARAMETER CCSID UNICODE(对于 Unicode 数据库)和 PARAMETER CCSID ASCII(对于所有其他数据库)。
ASCII
指定字符串数据以数据库代码页编码。 如果该数据库是 Unicode 数据库,那么不能指定 PARAMETER CCSID ASCII (SQLSTATE 56031)。 调用该函数时,该函数的应用程序代码页是数据库代码页。
UNICODE
指定字符串数据以 Unicode 编码。 如果该数据库是 Unicode 数据库,那么字符数据将以 UTF-8 编码,图形数据以 UCS-2 编码。 如果该数据库不是 Unicode 数据库,那么字符数据将以 UTF-8 编码。 在任一情况下,调用该函数时,该函数的应用程序代码页为 1208。

如果数据库不是 Unicode 数据库,并且创建了具有 PARAMETER CCSID UNICODE 的函数,那么该函数不能具有任何图形类型, XML 类型或用户定义的类型 (SQLSTATE 560C1)。

如果数据库不是 Unicode 数据库,并且在数据库配置中指定了备用整理顺序,那么可以使用 PARAMETER CCSID ASCII 或 PARAMETER CCSID UNICODE 来创建函数。 所有传入和传入函数的字符串数据都将转换为相应的代码页。

此子句不能与 LANGUAGE CPP , LANGUAGE OLE , LANGUAGE JAVA 或 LANGUAGE CLR 一起指定 (SQLSTATE 42613)。

DETERMINISTIC 或 NOT DETERMINISTIC
此可选子句指定函数是否始终对给定的参数值返回相同的结果 (DETERMINISTIC),或者函数是否依赖于影响结果的某些状态值 (NOT DETERMINISTIC)。 也就是说,DETERMINISTIC 函数必须始终从具有相同输入的连续调用中返回相同的结果。 通过指定 NOT DETERMINISTIC 可以防止利用相同输入总是产生相同结果这一事实的优化。 NOT DETERMINISTIC 函数的一个示例是随机数生成器。 DETERMINISTIC 函数的一个示例是确定输入平方根的函数。
FENCED NOT FENCED
此子句指定是否将该函数视为 安全 以在数据库管理器操作环境的进程或地址空间中运行。

如果某个函数注册为 FENCED ,那么数据库管理器将保护其内部资源 (例如,数据缓冲区) 不受该函数访问。 大多数函数都可以选择作为 FENCED 或 NOT FENCED 运行。 通常,以 FENCED 方式运行的函数不会像以 NOT FENCED 方式运行的类似函数那样执行。

注意:
对未进行充分编码,复审和测试的函数使用 NOT FENCED 会损害数据库的完整性。 此数据库产品可防止可能发生的许多常见类型的意外故障,但在使用 NOT FENCED 用户定义的函数时无法保证完全完整性。

只能对具有 LANGUAGE OLE 或 NOT THREADSAFE 的函数指定 FENCED (SQLSTATE 42613)。

如果函数是 FENCED 并且具有 NO SQL 选项,那么不能指定 AS LOCATOR 子句 (SQLSTATE 42613)。

指定 NOT FENCED 子句时,无法创建 LANGUAGE CLR 用户定义的函数 (SQLSTATE 42601)。

THREADSAFE NOT THREADSAFE
指定是否认为可在与其他例程相同的进程中安全运行该函数(安全 (THREADSAFE) 或不安全 (NOT THREADSAFE))。
如果使用除 OLE 以外的 LANGUAGE 定义函数:
  • 如果将该函数定义为 THREADSAFE,那么数据库管理器可以在与其他例程相同的进程中调用该函数。 通常,作为线程安全函数,函数不应使用任何全局或静态数据区域。 大部分编程参考资料都会包括有关编写线程安全例程的探讨。 FENCED 和 NOT FENCED 函数都可以是 THREADSAFE。
  • 如果将该函数定义为 NOT THREADSAFE,那么数据库管理器将永远不会在与另一个例程相同的进程中同时调用该函数。

对于 FENCED 函数,如果 LANGUAGE 为 JAVA 或 CLR,那么 THREADSAFE 是缺省值。 对于所有其他语言,缺省值为 NOT THREADSAFE。 如果使用 LANGUAGE OLE 定义函数,那么可能未指定 THREADSAFE (SQLSTATE 42613)。

对于 NOT FENCED 函数,缺省值为 THREADSAFE。 不得指定 NOT THREADSAFE (SQLSTATE 42613)。

在空输入上返回空值 在空输入上调用
此可选子句可用于避免在任何自变量为空时调用外部函数。 如果将用户定义的函数定义为没有参数,那么不会出现此空参数条件,并且此规范的编码方式无关紧要。 如果未指定此子句,那么缺省值为 RETURNS NULL ON NULL INPUT ,除非指定了 PARAMETER STYLE JAVA ,在这种情况下,缺省值为调用 NULL INPUT。

如果指定了 RETURNS NULL ON NULL INPUT ,并且在执行时,如果函数的任何一个自变量为空,那么不会调用用户定义的函数,结果为空值。

如果指定了调用 ON NULL INPUT ,那么无论任何自变量是否为空,都将调用用户定义的函数。 它可以返回空值或正常 (非空) 值。 但是,对于空参数值的测试由 UDF 负责。

值 NULL CALL 可用作 CALL ON NULL INPUT 的同义词,以实现向后兼容和系列兼容。 类似地, NOT NULL CALL 可用作 RETURNS NULL ON NULL INPUT 的同义词。

READS SQL DATA , NO SQL 或 CONTAINS SQL
指定函数可以运行的 SQL 语句的分类。 数据库管理器验证函数问题的 SQL 语句是否与此规范一致。

有关每个语句的分类,请参阅 可在例程和触发器中执行的 SQL 语句

缺省值为 READS SQL DATA。

READS SQL DATA
指定函数可以运行数据访问分类为 READS SQL DATA , CONTAINS SQL 或 NO SQL (SQLSTATE 38002 或 42985) 的语句。 该函数无法运行用于修改数据的 SQL 语句。 (SQLSTATE 38003 或 42985)。
NO SQL
指定该函数只能运行数据访问分类为 NO SQL 的 SQL 语句 (SQLSTATE 38001)。
CONTAINS SQL
指定函数只能运行数据访问分类为 CONTAINS SQL 或 NO SQL 的 SQL 语句 (SQLSTATE 38004 或 42985)。 该函数无法运行任何读取或修改数据的 SQL 语句 (SQLSTATE 38003 或 42985)。
静态分派
此可选子句指示在函数解析时,数据库服务器根据函数参数的静态类型 (声明类型) 选择函数。
EXTERNAL ACTION NO EXTERNAL ACTION
指定函数是否执行操作来更改数据库管理器不管理的对象的状态。 外部操作的一个示例是发送消息或将记录写入文件。 缺省值为 EXTERNAL ACTION。
EXTERNAL ACTION
指定函数执行更改数据库管理器不管理的对象的状态的操作。

如果函数由并行任务执行,则具有外部操作的函数可能会返回不正确的结果。 例如,如果函数为每个初始调用发送一个注释,则为每个并行任务发送一个注释,而不是为函数发送一个注释。 对不能正确使用并行性的函数指定 DISALLOW PARALLEL 子句。

NO EXTERNAL ACTION
指定函数不执行任何更改数据库管理器不管理的对象的状态的操作。 数据库管理器在优化 SQL 语句期间使用此信息。
无 SCRATCHPAD SCRATCHPAD 长度
此可选子句可用于指定是否为外部函数提供暂存区。 (强烈建议重新输入用户定义的函数,因此暂存区为函数提供了从一个调用到下一个调用的 保存状态 方法。)
  • 如果指定了 SCRATCHPAD ,那么在第一次调用用户定义的函数时,将为要由外部函数使用的暂存区分配内存。 在每次调用用户定义的函数时,都会向外部函数传递一个额外的自变量,该自变量用于对暂存区进行寻址。 此暂存区具有以下特征:
    • length(如果指定) 设置暂存区的大小 (以字节计); 此值必须介于 1 与 32 767 之间 (SQLSTATE 42820)。 缺省大小为 100 字节。
    • 它已初始化为所有 X'00 ''。
    • 其作用域为 SQL 语句。 对于 SQL 语句中的外部函数,每个引用都有一个暂存区。 因此,如果使用 SCRATCHPAD 关键字定义了以下语句中的 UDFX 函数,那么将分配三个暂存区。
         SELECT A, UDFX(A) FROM TABLEB
           WHERE UDFX(A) > 103 OR UDFX(A) < 19

      如果指定或缺省为 ALLOW PARALLEL ,那么作用域与先前显示的作用域不同。 如果在多个数据库分区中执行该函数,那么对于 SQL 语句中对该函数的每个引用,将在处理该函数的每个数据库分区中分配一个暂存区。 同样,如果在启用分区内并行性的情况下执行查询,那么可能会分配三个以上的暂存区。

    • 它是持久的。 其内容从一个外部函数调用保留到下一个外部函数调用。 在一次调用时,外部函数对暂存区进行的任何更改都将在下一次调用时出现。 数据库管理器在开始执行每个 SQL 语句时初始化暂存区。 数据库管理器可以在每个子查询的执行开始时重置暂存区。 如果指定了 FINAL CALL 选项,那么系统将在重置暂存区之前发出最终调用。
    • 它可以用作外部函数可能获取的系统资源 (例如,内存) 的中心点。 该函数可以在第一次调用时获取内存,将其地址保留在暂存区中,并在后续调用中引用该内存。

      (在获取系统资源的情况下,还应指定 FINAL CALL 关键字; 这将导致在语句结束时进行特殊调用,以允许外部函数释放所获取的任何系统资源。)

  • 如果指定了 NO SCRATCHPAD ,那么不会分配任何暂存区或将任何暂存区传递给外部函数。

SCRATCHPAD 不能与 PARAMETER STYLE JAVA 函数一起指定。

FINAL CALL NO FINAL CALL
此可选子句指定是否对外部函数进行最终调用。 此类最终调用的目的是使外部函数能够释放其已获取的任何系统资源。 在外部函数获取系统资源 (例如内存) 并将其固定在暂存区中的情况下,它可以与 SCRATCHPAD 关键字一起使用。
  • 如果指定了 FINAL CALL ,那么在执行时,将向指定调用类型的外部函数传递附加参数。 调用类型为:
    NORMAL 调用
    将传递 SQL 自变量,并且期望返回结果。
    FIRST 调用
    对此 SQL 语句中用户定义的函数的引用的第一次外部函数调用。 第一个呼叫是正常呼叫。
    FINAL 调用
    对外部函数的最终调用,使该函数能够释放资源。 最终调用不是正常调用。 此最终调用发生在以下时间:
    语句结束
    当针对面向游标的语句关闭游标时,或者当语句通过其他方式执行时,将发生此情况。
    并行结束任务
    当函数由并行任务执行时,会发生此情况。
    事务结束或中断
    当未发生正常的语句结束时,将发生此情况。 例如,应用程序的逻辑可能由于某种原因而绕过游标的关闭。 在此类型的最终调用期间,除 CLOSE 游标外,不得发出任何 SQL 语句 (SQLSTATE 38505)。 此类型的最终调用由 call type 自变量中的特殊值指示。
    如果在定义为 WITH HOLD 的游标打开时发生落实操作,那么将在游标的后续关闭或应用程序结束时进行最终调用。
  • 如果未指定 FINAL CALL ,那么不会将任何 call type 参数传递到外部函数,也不会进行最终调用。
不能将 FINAL CALL 与以下参数设置一起指定:
  • PARAMETER STYLE JAVA
  • language cpp
允许并行 不允许并行
此可选子句指定函数的调用能否并行化(对于函数的单个引用)。 通常,大多数标量函数的调用应该是可并行的,但可能有函数 (例如依赖于暂存区的单个副本的函数) 不能。 如果为标量函数指定了 ALLOW PARALLEL 或 DISALLOW PARALLEL ,那么将接受此规范。 在确定哪个关键字适合该函数时,应考虑以下问题。
  • 所有 UDF 调用都完全独立吗? 如果是,那么指定 ALLOW PARALLEL。
  • 每个 UDF 调用是否都会更新暂存区,从而提供下一个调用所关注的值? (例如,计数器递增。) 如果是,那么指定 DISALLOW PARALLEL 或接受缺省值。
  • UDF 是否执行了某些仅应在一个数据库分区上发生的外部操作? 如果是,那么指定 DISALLOW PARALLEL 或接受缺省值。
  • 是否使用了暂存区,但仅如此,可以执行一些昂贵的初始化处理的次数极少? 如果是,那么指定 ALLOW PARALLEL。
  • 是否要在访问 按列组织的 表的查询中调用该函数? 如果是,那么指定 ALLOW PARALLEL 可能会提高性能。

在任何情况下,每个外部函数的主体都应该位于每个数据库分区上可用的目录中。

缺省值为 ALLOW PARALLEL ,除非在语句中指定了以下一个或多个选项。
  • NOT DETERMINISTIC
  • EXTERNAL ACTION
  • SCRATCHPAD
  • FINAL CALL
如果指定或隐含其中任何选项,那么缺省值为 DISALLOW PARALLEL。
INHERIT SPECIAL REGISTERS
此可选子句指定函数中的可更新专用寄存器将从调用语句的环境继承其初始值。 对于在游标的 SELECT 语句中调用的函数,在打开游标时将从环境继承初始值。 对于在嵌套对象(例如触发器或视图)中调用的例程,将从运行时环境继承初始值(而不是从对象定义继承)。

不会将对专用寄存器的任何更改传递回函数的调用者。

不可更新的专用寄存器(例如,日期时间专用寄存器)反映当前正在执行的语句的属性,因此会设置为它们的缺省值。

无 DBINFO DBINFO
此可选子句指定是否将数据库服务器已知的特定信息作为附加调用时参数 (DBINFO) 传递给 UDF (NO DBINFO)。 缺省值为 NO DBINFO。 以下子句不支持 DBINFO (SQLSTATE 42613):
  • LANGUAGE OLE
  • PARAMETER STYLE JAVA
如果指定了 DBINFO ,那么会将结构传递到包含以下信息的 UDF:
  • 数据库名称 - 当前连接的数据库的名称。
  • 应用程序标识 - 针对每个数据库连接建立的唯一应用程序标识。
  • 应用程序授权标识-应用程序运行时授权标识,而不考虑此 UDF 与应用程序之间的嵌套 UDF。
  • 代码页 - 识别数据库代码页。
  • 模式名称-在与表名完全相同的条件下,包含模式的名称; 否则为空白。
  • 表名-当且仅当 UDF 引用是 UPDATE 语句中 SET 子句的右侧或 INSERT 语句的 VALUES 列表中的项时,包含正在更新或插入的表的非限定名; 否则为空白。
  • 列名-在与表名完全相同的条件下,包含要更新或插入的列的名称; 否则为空白。
  • 数据库版本/发行版-标识调用 UDF 的数据库服务器的版本,发行版和修改级别。
  • 平台 - 包含服务器的平台类型。
  • 表函数结果列号-不适用于外部标量函数。
TRANSFORM GROUP group-name
指示在调用函数时要用于用户定义的结构化类型变换的变换组。 如果函数定义包含用户定义的结构化类型作为参数或返回数据类型,那么需要变换。 如果未指定此子句,那么将使用缺省组名 DB2_FUNCTION 。 如果没有为引用的结构化类型定义指定的 (或缺省值) group-name ,那么会发生错误 (SQLSTATE 42741)。 如果没有为给定组名和结构化类型定义必需的 FROM SQL 或 TO SQL 变换函数,那么会发生错误 (SQLSTATE 42744)。

无论是指定的还是隐式的 FROM SQL 和 TO SQL 变换函数都必须是在结构化类型及其内置类型属性之间进行正确变换的 SQL 函数。

谓词
定义在谓词中使用此函数时执行的过滤或索引扩展利用。 谓词规范允许指定搜索条件的可选选择性子句。 如果指定了 PREDICATES 子句,那么必须将该函数定义为具有 NO EXTERNAL ACTION 的确定性函数 (SQLSTATE 42613)。 如果指定了 PREDICATES 子句,并且数据库不是 UNICODE 数据库,那么不得指定 PARAMETER CCSID UNICODE (SQLSTATE 42613)。
WHEN 比较运算符
引入了在谓词中使用比较运算符 (=<>>=<=<>) 的函数的特定用法。
constant
指定数据类型与函数的 RETURNS 类型相当的常量值 (SQLSTATE 42818)。 当谓词将此函数与同一比较运算符和此常量配合使用时,优化器将考虑指定的过滤和索引利用。
EXPRESSION AS 表达式名称
提供表达式的名称。 当谓词将此函数与相同的比较运算符和表达式配合使用时,可以使用过滤和索引利用。 将为表达式指定表达式名称,以便可以将其用作搜索函数自变量。 expression-name 不能与正在创建的函数的任何 parameter-name 相同 (SQLSTATE 42711)。 指定表达式时,将标识表达式的类型。
过滤器使用
允许指定外部函数或案例表达式以用于对结果表进行其他过滤。
函数调用
指定可用于对结果表执行其他过滤的过滤器函数。 这是定义的函数 (在谓词中使用) 的版本,用于减少必须执行用户定义的谓词的行数,以确定行是否合格。 如果索引生成的结果接近用户定义谓词的预期结果,那么应用过滤函数可能是多余的。 如果未指定,那么不会执行数据过滤。

此函数可以使用任何 parameter-nameexpression-name或常量作为自变量 (SQLSTATE 42703) ,并返回整数 (SQLSTATE 428E4)。 返回值 1 表示保留该行,否则将废弃该行。

此函数还必须:
  • 未使用 LANGUAGE SQL 定义 (SQLSTATE 429B4)
  • 未使用 NOT 确定性或 EXTERNAL ACTION 定义 (SQLSTATE 42845)
  • 没有结构化数据类型作为任何参数的数据类型 (SQLSTATE 428E3)
  • 不包含子查询 (SQLSTATE 428E4)
  • 不包含 XMLQUERY 或 XMLEXISTS 表达式 (SQLSTATE 428E4)
如果自变量调用另一个函数或方法,那么也会对此嵌套函数或方法实施这些规则。 但是,只要自变量求值为内置数据类型,就允许系统生成的观察器方法作为过滤器函数 (或用作自变量的任何函数或方法) 的自变量。

函数的定义者必须对指定的过滤器函数具有 EXECUTE 特权。

在数据库代码页中, function-调用 子句的长度不得超过 65 536 字节 (SQLSTATE 22001)。

case表达式
指定用于对结果表进行其他过滤的案例表达式。 已搜索-when-clausesimple-when-clause 可以使用 parameter-nameexpression-name或常量 (SQLSTATE 42703)。 具有 FILTER USING function-调用 中指定的规则的外部函数可用作结果表达式。 case-expression 中引用的任何函数或方法也必须符合 function-调用下列出的四个规则。

不能在 case-expression 中的任何位置使用子查询和 XMLQUERY 或 XMLEXISTS 表达式 (SQLSTATE 428E4)。

案例表达式必须返回整数 (SQLSTATE 428E4)。 结果表达式中的返回值 1 表示保留该行; 否则将废弃该行。

在数据库代码页中, case-调用 子句的长度不得超过 65 536 字节 (SQLSTATE 22001)。

索引利用
根据可用于利用索引的索引扩展的搜索方法定义一组规则。
按索引扩展搜索 index-extension-name
标识索引扩展。 index-extension-name 必须标识现有索引扩展。
EXACT
指示索引查找在谓词求值方面是精确的。 使用 EXACT 指示在索引查找后不需要应用原始用户定义谓词函数或过滤器。 当索引查找返回与谓词相同的结果时, EXACT 谓词很有用。

如果未指定 EXACT ,那么将在索引查找之后应用原始用户定义谓词。 如果期望索引仅提供谓词的近似值,请不要指定 EXACT 选项。

如果不使用索引查找,那么必须应用过滤函数和原始谓词。

利用-规则
描述搜索目标和搜索参数以及如何使用它们通过索引扩展中定义的搜索方法来执行索引搜索。
当键 ( parameter-name1 )
这将定义搜索目标。 只能为一个键指定一个搜索目标。 parameter-name1 值标识已定义函数的参数名称 (SQLSTATE 42703 或 428E8)。

parameter-name1 的数据类型必须与索引扩展中指定的源键的数据类型相匹配 (SQLSTATE 428EY)。 对于内置数据类型和单值数据类型,该匹配必须精确,并且必须在结构化类型的同一结构化类型层次结构中。

当指定参数的值是由基于指定索引扩展的索引覆盖的列时,此子句成立。

使用 search-method-name ( parameter-name2 )
这将定义搜索参数。 它从索引扩展中定义的搜索方法标识要使用的搜索方法。 search-method-name 必须与索引扩展中定义的搜索方法匹配 (SQLSTATE 42743)。 parameter-name2 值标识已定义函数的参数名称或 EXPRESSION AS 子句中的 expression-name (SQLSTATE 42703)。 它必须与搜索目标中指定的任何参数名称不同 (SQLSTATE 428E9)。 每个 parameter-name2 的参数数目和数据类型必须与为索引扩展中的搜索方法定义的参数相匹配 (SQLSTATE 42816)。 对于内置数据类型和单值数据类型,该匹配必须精确,并且必须在结构化类型的同一结构化类型层次结构中。
NOT SECURED 或 SECURED
指定函数是否被认为对行和列访问控制是安全的。 缺省值为 NOT SECURED。
NOT SECURED
指示该函数未被视为安全函数。 调用函数时,函数的参数不得引用已启用列掩码且为其表激活列级访问控制的列 (SQLSTATE 428HA)。 此规则适用于在语句中任何位置调用的非安全用户定义函数。
SECURED
指示该功能被视为安全功能。 在行权限或列掩码中引用该函数时,该函数必须是安全的 (SQLSTATE 428H8)。
STAY RESIDENT NO
指定在函数结束后,为该函数装入的库不会驻留在内存中。 在以下情况下,将会忽略此子句:
  • 指定了 NOT FENCED 子句。
  • LANGUAGE 选项设置为 JAVA 或 CLR。

注意

  • 确定一个数据类型是否可强制转换为另一数据类型不考虑长度或精度以及参数化数据类型 (例如 CHAR 和 DECIMAL) 的小数位。 因此,在尝试将源数据类型的值强制转换为目标数据类型的值时,使用函数时可能会发生错误。 例如, VARCHAR 可强制转换为 DATE ,但如果源类型实际定义为 VARCHAR (5) ,那么使用该函数时将发生错误。
  • 为用户定义的函数的参数选择数据类型时,请考虑将影响其输入值的提升规则 (请参阅 提升数据类型)。 例如,可以用作输入值的常量可能具有与期望的数据类型不同的内置数据类型,更重要的是,可能不会提升到期望的数据类型。 根据促销规则,通常建议对参数使用以下数据类型:
    • INTEGER 而不是 SMALLINT
    • DOUBLE 而不是 REAL
    • VARCHAR 而不是 CHAR
    • VARGRAPHIC 而不是 GRAPHIC
  • 对于跨平台的 UDF 的可移植性,不应使用以下数据类型:
    • FLOAT-改为使用 DOUBLE 或 REAL。
    • NUMERIC-改为使用 DECIMAL。
    • LONG VARCHAR-改为使用 CLOB (或 BLOB)。
  • 函数和方法可能不在覆盖关系中 (SQLSTATE 42745)。 有关覆盖的更多信息,请参阅 CREATE TYPE (结构化)
  • 函数可能与方法具有不同的特征符 (将函数的第一个 参数类型 与方法的 主题类型 进行比较) (SQLSTATE 42723)。
  • 创建具有尚不存在的模式名称的函数将导致隐式创建该模式,前提是该语句的授权标识具有 IMPLICIT_SCHEMA 权限。 模式所有者是 SYSIBM。 该模式上的 CREATEIN 特权会授予 PUBLIC。
  • 在分区数据库环境中,不支持在外部用户定义的函数或方法中使用 SQL (SQLSTATE 42997)。
  • 只能使用定义为 NO SQL 的例程来定义索引扩展 (SQLSTATE 428F8)。
  • 如果该函数允许 SQL ,那么外部程序不得尝试访问任何联合对象 (SQLSTATE 55047)。
  • 将调用定义为 NOT FENCED 的 JAVA 例程,就像它已定义为 FENCED THREADSAFE 一样。
  • 仅当指定了 PARAMETER STYLE DB2GENERAL 子句时,仅在 LANGUAGE JAVA 外部函数中支持 XML 参数。
  • 表访问限制

    如果函数定义为 READS SQL DATA ,那么该函数中的任何语句都不能访问正在由调用该函数的语句修改的表 (SQLSTATE 57053)。 例如,假设用户定义的函数 BONUS () 定义为 READS SQL DATA。 如果调用了语句 UPDATE EMPLOYEE SET SALARY = SALARY + 奖金 (EMPNO) ,那么不会从 EMPLOYEE 表中读取函数中的 SQL 语句。

  • 缺省值的设置: 使用缺省值定义的函数的参数在调用函数时设置为其缺省值,但仅当没有为相应的自变量提供值时,或者在调用函数时指定为 DEFAULT 时,才会设置为其缺省值。
  • 特权: 函数的定义者始终接收对该函数的 EXECUTE 特权 WITH GRANT OPTION 以及删除该函数的权限。

    在 SQL 语句中使用该函数时,该函数定义者必须对该函数所使用的任何程序包具有 EXECUTE 特权,或者对包含这些程序包的模式具有 EXECUTEIN 特权或 DATAACCESS 权限。

  • EXTERNAL ACTION 函数: 如果在非最外层选择列表中调用 EXTERNAL ACTION 函数,那么结果不可预测,因为调用该函数的次数将根据所使用的存取方案而有所不同。
  • 语法替代方法: 为了与此数据库产品的先前版本以及其他数据库产品兼容,支持以下语法替代方法。 这些备用项是非标准的,不应使用。
    • 可以指定 PARAMETER STYLE $TAG1 DB2SQL $TAG2 来代替 PARAMETER STYLE SQL
    • 可以指定 NOT VARIANT 来代替确定性,也可以指定 VARIANT 来代替 NOT 确定性
    • 可以指定 NULL CALL 来代替 CALL ON NULL INPUT ,也可以指定 NOT NULL CALL 来代替 RETURNS NULL ON NULL INPUT
    接受将下列语法作为缺省行为:
    • ASUTIME NO LIMIT
    • NO COLLID
    • PROGRAM TYPE SUB
    • STAY RESIDENT NO
    • Unicode 数据库中的 CCSID UNICODE
    • 非 Unicode 数据库中的 CCSID ASCII(如果未指定 PARAMETER CCSID UNICODE)
  • 创建安全函数: 通常,具有 SECADM 权限的用户没有创建数据库对象 (例如触发器和函数) 的特权。 通常; 他们将检查该函数访问的数据,确保其安全,然后将 CREATE_SECURE_OBJECT 权限授予当前具有创建安全用户定义的函数所需的特权的人员。 创建函数后,它们将撤销函数所有者的 CREATE_SECURE_OBJECT 权限。

    SECURED 属性被认为是一种断言,用于声明用户已为用户定义函数的所有更改建立了更改控制审计过程。 数据库管理器假定所有后续 ALTER FUNCTION 语句或对外部包的更改都存在这样的控制审计过程。

  • 在安全函数中调用其他用户定义的函数: 如果安全用户定义的函数调用其他用户定义的函数,那么数据库管理器不会验证这些嵌套的用户定义的函数是否具有 SECURE 属性。 如果这些嵌套函数可以访问敏感数据,那么具有 SECADM 权限的用户需要确保允许这些函数访问这些数据,并且已经为这些函数的所有更改建立了更改控制审计过程。
  • 替换现有函数,以便将安全属性从 "受保护" 更改为 "不受保护" ,反之亦然): 依赖于该函数的程序包和动态高速缓存的 SQL 语句可能会失效,因为该安全属性会影响涉及已激活行或列级别访问控制的表的语句的访问路径选择。

示例

  1. Pellow 正在其 PELLOW 模式中注册 CENTER 函数。 让那些将默认的关键字这样做,并让系统提供一个特定于函数的名称:
       CREATE FUNCTION CENTER (INT,FLOAT)
         RETURNS FLOAT
         EXTERNAL NAME 'mod!middle'
         LANGUAGE C
         PARAMETER STYLE SQL
         DETERMINISTIC
         NO SQL
         NO EXTERNAL ACTION
  2. 现在, McBride (具有 DBADM 权限) 正在 PELLOW 模式中注册另一个 CENTER 函数,为其提供显式的特定名称以供后续数据定义语言使用,并显式提供所有关键字值。 另请注意,此函数使用暂存区,并且可能正在那里累积影响后续结果的数据。 由于指定了 DISALLOW PARALLEL ,因此对该函数的任何引用都不会并行化,因此将使用单个暂存区来执行一些仅一次性初始化并保存结果。
       CREATE FUNCTION PELLOW.CENTER (FLOAT, FLOAT, FLOAT)
         RETURNS DECIMAL(8,4) CAST FROM FLOAT
         SPECIFIC FOCUS92
         EXTERNAL NAME 'effects!focalpt'
         LANGUAGE C   PARAMETER STYLE SQL
         DETERMINISTIC   FENCED   NOT NULL CALL   NO SQL   NO EXTERNAL ACTION
         SCRATCHPAD   NO FINAL CALL 
         DISALLOW PARALLEL
  3. 以下示例是为实现规则 output = 2 * input - 4 而编写的 C 语言用户定义的函数程序,仅当且仅当输入为空时返回 NULL。 如果 CREATE FUNCTION 语句使用了 NOT NULL CALL ,那么可以更简单 (即,不进行空值检查) 编写此函数。 CREATE FUNCTION 语句:
       CREATE FUNCTION ntest1 (SMALLINT)
         RETURNS SMALLINT
         EXTERNAL NAME 'ntest1!nudft1'
         LANGUAGE C    PARAMETER STYLE SQL
         DETERMINISTIC   NOT FENCED   NULL CALL
         NO SQL   NO EXTERNAL ACTION
    程序代码:
    #include "sqlsystm.h"
    /* NUDFT1 IS A USER_DEFINED SCALAR FUNCTION */
    /* udft1 accepts smallint input
    and produces smallint output
    implementing the rule:
    if (input is null)
    set output = null;
    else
    set output = 2 * input - 4;
    */
    void SQL_API_FN nudft1
    (short *input,      /* ptr to input arg */
    short *output,     /* ptr to where result goes */
    short *input_ind,  /* ptr to input indicator var */
    short *output_ind, /* ptr to output indicator var */
    char sqlstate[6],  /* sqlstate, allows for null-term */
    char fname[28],    /* fully qual func name, nul-term */
    char finst[19],    /* func specific name,  null-term */
    char msgtext[71])  /* msg text buffer,     null-term */
    {
    /* first test for null input */
    if (*input_ind == -1)
    {
    /* input is null, likewise output */
    *output_ind = -1;
    }
    else
    {
    /* input is not null.  set output to 2*input-4 */
    *output = 2 * (*input) - 4;
    /* and set out null indicator to zero */
    *output_ind = 0;
    }
    /* signal successful completion by leaving sqlstate as is */
    /* and exit */
    return;
    }
    /* end of UDF: NUDFT1 */
  4. 以下示例注册 Java UDF ,该 UDF 返回字符串中第一个元音的位置。 UDF 以 Java 编写,将运行受防护,并且是类 javaUDFs的 findvwl 方法。
       CREATE FUNCTION findv ( CLOB(100K))
         RETURNS INTEGER
         FENCED
         LANGUAGE JAVA
         PARAMETER STYLE JAVA
         EXTERNAL NAME 'javaUDFs.findvwl'
         NO EXTERNAL ACTION
         CALLED ON NULL INPUT 
         DETERMINISTIC
         NO SQL
  5. 此示例概述了用户定义的谓词 WITHIN ,该谓词采用两个类型为 SHAPE 的参数 g1 和 g2作为输入:
    CREATE FUNCTION within (g1 SHAPE, g2 SHAPE)
    RETURNS INTEGER
    LANGUAGE C
    PARAMETER STYLE SQL
    DETERMINISTIC
    NOT FENCED
    NO SQL
    NO EXTERNAL ACTION
    EXTERNAL NAME 'db2sefn!SDESpatilRelations'
    PREDICATES
    WHEN = 1
    FILTER USING mbrOverlap(g1..xmin, g1..ymin, g1..xmax, g1..max,
    g2..xmin, g2..ymin, g2..xmax, g2..ymax)
    SEARCH BY INDEX EXTENSION gridIndex
    WHEN KEY(g1) USE withinExplRule(g2)
    WHEN KEY(g2) USE withinExplRule(g1)
    WITHIN 函数的描述与任何用户定义的函数的描述相似,但以下添加项指示此函数可以在用户定义的谓词中使用。
    • PREDICATES WHEN = 1 指示当此函数显示为
         within(g1, g2) = 1
      在 DML 语句的 WHERE 子句中,谓词将被视为用户定义的谓词,并且应该使用索引扩展 gridIndex 定义的索引来检索满足此谓词的行。 如果指定了常量,那么 DML 语句期间指定的常量必须与 create index 语句中指定的常量完全匹配。 提供此条件主要是为了涵盖结果类型为 1 或 0 的布尔表达式。 对于其他情况, EXPRESSION 子句是更好的选择。
    • FILTER USINGmbrOverlap指的是过滤函数mbrOverlap,它是 WITHIN 谓词的廉价版本。 在此示例中, mbrOverlap 函数采用最小边界矩形作为输入,并快速确定它们是否重叠。 如果两个输入形状的最小边界矩形不重叠,那么 g1 将不会与 g2一起包含。 因此可以安全地废弃元组,避免应用昂贵的 WITHIN 谓词。
    • SEARCH BY INDEX EXTENSION 子句指示可以将索引扩展和搜索目标的组合用于此用户定义的谓词。
  6. 此示例概述了用户定义的谓词 DISTANCE ,该谓词采用类型为 POINT 的两个参数 P1 和 P2作为输入:
       CREATE FUNCTION distance (P1 POINT, P2 POINT)
         RETURNS INTEGER
         LANGUAGE C
         PARAMETER STYLE SQL
         DETERMINISTIC
         NOT FENCED
         NO SQL
         NO EXTERNAL ACTION
         EXTERNAL NAME 'db2sefn!SDEDistances'
         PREDICATES
         WHEN > EXPRESSION AS distExpr
         SEARCH BY INDEX EXTENSION gridIndex
         WHEN KEY(P1) USE distanceGrRule(P2, distExpr)
         WHEN KEY(P2) USE distanceGrRule(P1, distExpr)

    DISTANCE 函数的描述与任何用户定义的函数的描述相似,但以下添加项指示在谓词中使用此函数时,该谓词是用户定义的谓词。

    • PREDICATES WHEN> EXPRESSION AS distExpr 是另一个有效谓词规范。 在 WHEN 子句中指定表达式时,该表达式的结果类型用于确定谓词是否是 DML 语句中的用户定义谓词。 例如:
         SELECT T1.C1
           FROM T1, T2
           WHERE distance (T1.P1, T2.P1) > T2.C2

      谓词规范距离采用两个参数作为输入,并将结果与 T2.C2,类型为 INTEGER。 由于只有右侧表达式的数据类型才重要 (而不是使用特定常量) ,因此最好在 CREATE FUNCTION DDL 中选择 EXPRESSION 子句以指定通配符作为比较值。

      或者,以下语句也是有效的用户定义谓词:
         SELECT T1.C1
           FROM T1, T2
           WHERE distance(T1.P1, T2.P1) > distance (T1.P2, T2.P2)
      当前有一个限制,只有右侧被视为表达式; 左侧的术语是用户定义谓词的用户定义函数。
    • SEARCH BY INDEX EXTENSION 子句指示可以将索引扩展和搜索目标的组合用于此用户定义的谓词。 对于距离函数,标识为 distExpr 的表达式也是传递到范围生产者函数 (定义为索引扩展的一部分) 的搜索自变量之一。 表达式标识用于定义表达式的名称,以便将其作为自变量传递至 range-Producer 函数。