CREATE FUNCTION(外部表)语句
CREATE FUNCTION (外部表) 语句用于在当前服务器上注册用户定义的外部表函数。
可以在 SELECT 的 FROM 子句中使用 表函数 ,并通过一次返回一行来将表返回到 SELECT。
调用
此语句可以嵌入在应用程序中,也可通过动态 SQL 语句来发出。 它是一个可执行语句,仅当 DYNAMICRULES 运行行为对于程序包有效时才能动态编译 (SQLSTATE 42509)。
授权
- 数据库上的 IMPLICIT_SCHEMA 权限 (如果函数的隐式或显式模式名不存在)。
- CREATEIN 对模式的特权 (如果函数的模式名引用现有模式)。
- 对模式的 SCHEMAADM 权限 (如果函数的模式名称引用现有模式)。
- DBADM 权限。
- CREATE_EXTERNAL_ROUTINE 对数据库的权限。
- SYSADM 权限。
- DBADM 权限 (如果设置了 DB2_ALTERNATE_AUTHZ_BEHAVIOUR 注册表变量并包含值 EXTERNAL_ROUTINE_DBADM)。
- 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 权限也隐式具有这些特权。
语法
- 1 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).
- 2 DB2SECURITYLABEL is the built-in distinct type that must be used to define the row security label column of a protected table.
- 3 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.
- 4 For information about creating LANGUAGE OLE DB external table
functions, see
CREATE FUNCTION (OLE DB External Table)
. For information about creating LANGUAGE SQL table functions, seeCREATE FUNCTION (SQL Scalar, Table, or Row)
.
描述
- OR REPLACE
- 指定替换当前服务器上存在的函数的定义。 在目录中替换新定义之前,现有定义将被有效删除,但授予函数的权限不受影响。 此选项只能由对象所有者指定。 如果函数的定义在当前服务器上不存在,那么忽略此选项。 要替换现有函数,新定义的特定名称和函数名必须与旧定义的特定名称和函数名相同,或者新定义的签名必须与旧定义的签名相匹配。 否则,将创建新函数。
如果在行许可权或列掩码的定义中引用了该函数,那么无法替换该函数 (SQLSTATE 42893)。
function-name - 命名要定义的函数。 它是指定函数的限定名称或非限定名称。 function-name 的非限定形式为 SQL 标识。 在动态 SQL 语句中,使用
CURRENT SCHEMA 专用寄存器作为未限定的对象名的限定符。 在静态 SQL 语句中,QUALIFIER
预编译/绑定选项隐式地指定未限定的对象名的限定符。 限定格式为 schema-name
后跟句点和 SQL 标识。 如果第一个参数是结构化类型,那么限定名不得与第一个参数的数据类型相同。
名称 (包括隐式或显式限定符) 以及参数数量和每个参数的数据类型 (不考虑数据类型的任何长度,精度或小数位属性) 不得标识目录中描述的函数 (SQLSTATE 42723)。 未限定的名称以及参数的数量和数据类型虽然在其模式中是唯一的,但不需要在模式之间是唯一的。
如果指定了两部分名称,则 schema-name 不能以
SYS
开头 (SQLSTATE 42939)。在谓词中用作关键字的多个名称保留供系统使用,并且不能用作 function-name (SQLSTATE 42939)。 名称包含 SOME、ANY、ALL、NOT、AND、OR、BETWEEN、NULL、LIKE、EXISTS、IN、UNIQUE、OVERLAPS、SIMILAR、MATCH 和比较运算符。
如果函数的特征符存在一些差异,那么可以对多个函数使用相同的名称。 虽然没有禁止它,但是外部用户定义的表函数不应该被赋予与内置函数相同的名称。
(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)。
- 参数名
- 指定输入参数的可选名称。 该名称不能与参数列表中的任何其他 parameter-name 相同 (SQLSTATE 42734)。 data-type1
- 指定输入参数的数据类型。 数据类型可以是内置数据类型,单值类型,结构化类型或引用类型。 有关每种内置数据类型的更完整描述,请参阅
CREATE TABLE
。 某些数据类型并非在所有语言中都受支持。 有关 SQL 数据类型与主语言数据类型之间的映射的详细信息,请参阅映射到嵌入式 SQL 应用程序中的 SQL 数据类型的数据类型
。- 日期时间类型参数作为字符数据类型传递,数据以 ISO 格式传递。
- DECIMAL (和 NUMERIC) 对于 LANGUAGE C 和 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)。
对于用户定义的结构化类型,相应的变换函数必须存在于关联的变换组中。
对于引用类型,如果参数未限定作用域,那么可以将参数指定为 REF (type-name)。
- 缺省值
- 指定参数的缺省值。 缺省值可以是常量,专用寄存器,全局变量,表达式或关键字 NULL。 可以指定为缺省值的专用寄存器与可以为列缺省值指定的专用寄存器相同 (请参阅 CREATE TABLE 语句中的 default-clause )。 通过使用表达式,可以指定其他专用寄存器作为缺省值。
该表达式可以是
Expressions
中描述的类型的任何表达式。 如果未指定缺省值,那么该参数没有缺省值,并且调用该过程时不得省略相应的自变量。 表达式 的最大大小为 64K 字节。缺省表达式不得修改 SQL 数据(SQLSTATE 428FL 或 SQLSTATE 429BL)。 该表达式必须与参数数据类型赋值兼容 (SQLSTATE 42821)。
不能为类型为 ARRAY , ROW 或 CURSOR 的参数指定缺省值 (SQLSTATE 429BB)。
- AS LOCATOR
- 指定将参数值的定位器传递到函数而不是实际值。 仅对具有 LOB 数据类型或基于 LOB 数据类型的单值类型的参数指定 AS LOCATOR (SQLSTATE 42601)。 传递定位器而不是值可能会导致传递到函数的字节数减少,尤其是当参数的值非常大时。
AS LOCATOR 子句对确定数据类型是否可以提升没有影响,也不影响函数解析中使用的函数特征符。
如果函数是 FENCED 并且具有 NO SQL 选项,那么不能指定 AS LOCATOR 子句 (SQLSTATE 42613)。
- 退货
- 指定函数的输出。
- 表
- 指定函数的输出是表。 此关键字后面的括号用于对表的列的名称和类型列表进行定界。 列表样式类似于没有其他规范 (例如,约束) 的简单 CREATE TABLE 语句的样式。 不允许超过 255 列 (SQLSTATE 54011)。
- 列名称
- 指定此列的名称。 不能限定该名称,并且不能将同一名称用于表的多个列。 data-type2
- 指定列的数据类型,并且可以是以特定语言编写的 UDF 参数所支持的任何数据类型,结构化类型除外 (SQLSTATE 42997)。
- AS LOCATOR
- 当 data-type2 是基于 LOB 类型的 LOB 类型或单值类型时,使用此选项指示函数正在返回结果表中实例化的 LOB 值的定位器。
在
CREATE FUNCTION (external scalar)
语句主题中讨论了用于此子句的有效类型。
- GENERIC TABLE
- 指定函数的输出是通用表。 仅当指定 LANGUAGE JAVA 子句和 PARAMETER STYLE DB2GENERAL 子句时,才允许使用此子句 (SQLSTATE 42613)。
- built-in-type
- 请参阅
CREATE TABLE
以获取内置数据类型的描述。 - SPECIFIC specific-name
- 为要定义的函数实例提供唯一名称。 对此函数执行 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 语句中使用该函数时,该库中的库和函数必须存在并且可从数据库服务器访问。
单引号内不允许有多余的空格。
- 库标识
- 标识包含函数的库名。 数据库管理器会查找该库,如下所示:
操作系统 库名位置
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 语句中使用该函数时,方法标识必须存在并且可从数据库服务器访问。
单引号内不允许有多余的空格。
- jar_id
- 识别在数据库中安装 JAR 集合时对其指定的 JAR 标识。 它可以是简单标识,也可以是模式限定标识。 例如'myJar'和'mySchema.myJar' 类标识
- 标识 Java™ 对象的类标识。 如果类是软件包的一部分,类标识符部分必须包含完整的软件包前缀,例如'myPacks.UserFuncs'。 Java 虚拟机将在其中查找类的目录取决于操作系统,如下表中所示:
操作系统 Java 虚拟机将在其中查找类的目录
Linux
AIX
'.../myPacks/UserFuncs/' Windows '...\myPacks\UserFuncs\' method_id - 标识要调用的 Java 对象的方法名称。
- 对于 LANGUAGE CLR:
指定的 string 表示 .NET 组合件 (库或可执行文件) ,该组合件中的类以及数据库管理器为执行所创建的函数而调用的类中的方法。 执行 CREATE FUNCTION 语句时,模块,类和方法不需要存在。 但是,在 SQL 语句中使用该函数时,模块,类和方法必须存在并且可从数据库服务器访问; 否则,将返回错误 (SQLSTATE 42724)。
使用“/clr”编译器选项(指出例程包括受管代码扩展)编译的 C++ 例程必须编目为“LANGUAGE CLR”而非“LANGUAGE C”。 数据库服务器需要知道 .NET 基础结构正在用户定义的函数中使用,以便做出必要的运行时决策。 所有使用 .NET 基础结构的用户定义函数都必须编目为 "LANGUAGE CLR"。
名称必须括在单引号中。 不允许有多余的空格。
- 组合件
- 标识类所在的 DLL 或其他组合件文件。 必须指定任何文件扩展名 (例如 .dll)。 如果未提供完整路径名,那么该文件必须位于数据库产品的安装路径的函数目录中
例如,c:\sqllib\function。
如果文件位于安装函数目录的子目录中,那么可以在文件名之前给出子目录,而不是指定完整路径。
例如,如果安装目录为 c:\sqllib ,而组合件文件为 c:\sqllib\function\myprocs\mydotnet.dll,那么仅需要为组合件指定 "myprocs\mydotnet.dll"。
此参数是否区分大小写与文件系统相同。
类标识 - 指定给定组合件中的类名,要调用的方法位于该类中。 如果该类驻留在名称空间中,那么除了指定该类之外,还必须提供完整的名称空间。 例如,如果类 EmployeeClass 在名称空间 MyCompany.ProcedureClasses 中,那么必须为该类指定 MyCompany.ProcedureClasses.EmployeeClass。 请注意,某些 .NET 语言的编译器会添加项目名称来作为该类的名称空间,并且根据您是使用命令行编译器还是 GUI 编译器,行为可能有所不同。 此参数区分大小写。 method_id
- 指定给定的类中所要调用的方法。 此参数区分大小写。
- 标识类所在的 DLL 或其他组合件文件。 必须指定任何文件扩展名 (例如 .dll)。 如果未提供完整路径名,那么该文件必须位于数据库产品的安装路径的函数目录中
- 对于 LANGUAGE OLE:
指定的 string 是 OLE 程序化标识 (进步标识) 或类标识 (clsid) 以及方法标识,数据库管理器将调用此标识来执行正在创建的用户定义的函数。 当执行 CREATE FUNCTION 语句时,程序标识或类标识以及方法标识不需要存在。 但是,在 SQL 语句中使用该函数时,方法标识必须存在并且可从数据库服务器访问; 否则,将返回错误 (SQLSTATE 42724)。
单引号内不允许有多余的空格。
- 进度标识
- 识别 OLE 对象的程序化标识。
进度标识 未由数据库管理器解释,而仅在运行时转发到 OLE API。 指定的 OLE 对象必须是可创建的,并且支持后期绑定 (也称为基于 IDispatch 的绑定)。
clsid - 识别所要创建的 OLE 对象的类标识。 在 OLE 对象未向进度标识注册的情况下,可以将其用作指定 进度标识 的替代方法。 clsid
的格式如下:
{nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn}
其中,“n”是字母数字字符。 clsid 未由数据库管理器解释,而仅在运行时转发到 OLE API。
method_id - 识别所要调用的 OLE 对象的方法名。
- 识别 OLE 对象的程序化标识。
- 对于 LANGUAGE CPP:
指定的 string 是库中的库标识和类标识,其中包含数据库管理器为执行正在创建的用户定义函数而调用的评估方法。 如果未正确编排该字符串的格式,那么会返回错误 (SQLSTATE 42878)。
执行 CREATE FUNCTION 语句时,不需要库 (或库中的类) 存在。 但是,在 SQL 语句中使用该函数时,该库中的库和类必须存在并且可从数据库服务器访问; 否则,将返回错误 (SQLSTATE 42724)。
每个外部函数的主体应该位于每个数据库分区上可用的目录中。
可以按如下所示指定 string :单引号内不允许有多余的空格。- 库标识
- 包含函数的库的名称:
- 在 UNIX 系统上,如果指定的库标识为
myfunc,并且正在从/u/production运行数据库管理器,那么数据库管理器将在以下库中查找函数:/u/production/sqllib/function/myfunc - 在 Windows 操作系统上,数据库管理器在 LIBPATH 或 PATH 环境变量指定的目录路径中查找函数。
绝对路径标识 - 在 UNIX 系统上,如果指定的库标识为
- 包含函数的文件的完整路径。 例如:
- 在 UNIX 系统上,以下规范导致数据库管理器在
/u/jchui/mylib中查找 myfunc 共享库:'/u/jchui/mylib/myfunc' - 在 Windows 操作系统上,以下规范导致数据库管理器从
d:\mylib目录装入动态链接库 myfunc.dll :
如果使用绝对路径标识来标识例程主体,请确保附加 .dll 扩展名。'd:\mylib\myfunc.dll'
类标识 - 在 UNIX 系统上,以下规范导致数据库管理器在
- 包含要调用的方法的类的名称。
例如,如果指定'mymod!myclass':- 在 UNIX 系统上,数据库管理器查找库
$inst_home_dir/sqllib/function/mymod并在该库中调用 myclass 类的 evaluate 方法。 - 在 Windows 操作系统上,数据库管理器装入 mymod.dll 文件并在动态链接库 (DLL) 中调用 myclass 类的 evaluate 方法。
- 包含函数的库的名称:
- 对于 LANGUAGE C:
- 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 32 位操作系统中,此数据库产品的用户定义函数支持 LANGUAGE OLE。
有关创建 LANGUAGE OLE DB 外部表函数的信息,请参阅
CREATE FUNCTION (OLE DB 外部表)
。 - CPP
- 数据库管理器通过调用 C++ 类的 evaluate 方法来调用用户定义的函数。
- PARAMETER STYLE
- 此子句用于指定用于将参数传递到函数以及从函数返回值的约定。
- DB2GENERAL
- 用于指定用于将参数传递到 Java 类中定义为方法的外部函数并从这些函数返回值的约定。 仅当使用 LANGUAGE JAVA 时,才能指定此值。
- SQL
- 用于指定用于将参数传递到符合 C 语言调用和链接约定的外部函数, OLE 自动化对象所公开的方法 或 .NET 对象的公共静态方法的值并从中返回值的约定。 This must be specified when LANGUAGE C, LANGUAGE CLR , or LANGUAGE OLE is used.
- NPSGENERIC
用于指定用于将参数传递到 C++ 类中定义为方法的外部函数以及从这些函数返回值的约定。 仅当 LANGUAGE 选项设置为 CPP 时,才能指定此选项。
当将 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 的函数,那么该函数不能具有任何图形类型或用户定义的类型 (SQLSTATE 560C1)。
如果数据库不是 Unicode 数据库,那么可以使用 PARAMETER CCSID UNICODE 创建表函数,但以下规则适用:- 在创建表函数之前,必须在数据库配置中指定备用整理顺序 (SQLSTATE 56031)。 PARAMETER CCSID UNICODE 表函数使用数据库配置中指定的备用整理顺序进行整理。
- 使用 CCSID ASCII 创建的表或表函数以及使用 CCSID UNICODE 创建的表或表函数不能同时在单个 SQL 语句中使用 (SQLSTATE 53090)。 这适用于语句中直接引用的表和表函数,以及间接引用的表和表函数 (例如,通过引用完整性约束,触发器,具体化查询表和视图主体中的表)。
- 不能在 SQL 函数或 SQL 方法中引用使用 PARAMETER CCSID UNICODE 创建的表函数 (SQLSTATE 560C0)。
- 引用使用 PARAMETER CCSID UNICODE 创建的表函数的 SQL 语句不能调用 SQL 函数或 SQL 方法 (SQLSTATE 53090)。
- 图形类型, XML 类型和用户定义的类型不能用作 PARAMETER CCSID UNICODE 表函数的参数 (SQLSTATE 560C1)。
- 始终在数据库代码页中解释 SQL 语句。 特别是,这意味着文字、十六进制文字和定界标识中的每个字符都必须在数据库代码页中具有表示形式; 否则,该字符将替换为替换字符。
如果数据库不是 Unicode 数据库,并且在数据库配置中指定了备用整理顺序,那么可以使用 PARAMETER CCSID ASCII 或 PARAMETER CCSID UNICODE 来创建函数。 所有传入和传入函数的字符串数据都将转换为相应的代码页。
此子句不能与 LANGUAGE CPP , LANGUAGE OLE , LANGUAGE JAVA 或 LANGUAGE CLR 一起指定 (SQLSTATE 42613)。
- DETERMINISTIC 或 NOT DETERMINISTIC
- 此可选子句指定函数是否始终对给定的参数值返回相同的结果 (DETERMINISTIC),或者函数是否依赖于影响结果的某些状态值 (NOT DETERMINISTIC)。 即,确定性函数必须始终从具有相同输入的连续调用返回相同的表。 通过指定 NOT DETERMINISTIC 可以防止利用相同输入总是产生相同结果这一事实的优化。 非确定性表函数是指以影响表函数结果表的方式引用专用寄存器,全局变量,非确定性函数或序列的表函数的示例。
- FENCED 或 NOT FENCED
- 此子句指定是否将该函数视为
安全
在数据库管理器操作环境的进程或地址空间 (NOT FENCED) 中运行 (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 ,并且在表函数 OPEN 时,该函数的任何自变量都为空,那么不会调用用户定义的函数。 尝试的表函数扫描的结果是空表 (没有行的表)。
如果指定了调用 ON NULL INPUT ,那么无论任何自变量是否为空,都将调用用户定义的函数。 它可以返回空值或正常 (非空) 值。 但是,对于空参数值的测试由 UDF 负责。
值 NULL CALL 可用作 CALL ON NULL INPUT 的同义词,以实现向后兼容和系列兼容。 类似地, NOT NULL CALL 可用作 RETURNS NULL ON NULL INPUT 的同义词。
- 读取 SQL 数据,无 SQL ,包含 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 语句。 If the ALLOW PARALLEL, EXECUTE ON ALL 数据库分区, and RESULT TABLE DISTRIBUTED clauses are all specified, NO SQL is the only option allowed.
- 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.C1, B.C2 FROM TABLE (UDFX(:hv1)) AS A, TABLE (UDFX(:hv1)) AS B WHERE ... - 它是持久的。 它是在语句执行开始时初始化的,可以由外部表函数用来保留暂存区从一个调用到下一个调用的状态。 如果还为 UDF 指定了 FINAL CALL 关键字,那么暂存区是从不改变的,并且在进行特殊 FINAL 调用时应释放暂存区中的任何资源。
如果指定了 NO FINAL CALL 或缺省值,那么外部表函数应清除 CLOSE 调用上的任何此类资源,因为数据库服务器将在每个 OPEN 调用上重新初始化暂存区。 确定 FINAL CALL 或 NO FINAL CALL 以及暂存区的关联行为可能是一个重要的考虑因素,尤其是在表函数将用于子查询或连接时,因为在执行语句期间可能会发生多个 OPEN 调用。
- 它可以用作外部函数可能获取的系统资源 (例如,内存) 的中心点。 该函数可以在第一次调用时获取内存,将其地址保留在暂存区中,并在后续调用中引用该内存。
(如前所述, FINAL CALL/NO FINAL CALL 关键字用于控制暂存区的重新初始化,并指示外部表函数何时应释放暂存区中的资源。)
- 如果指定了 NO SCRATCHPAD ,那么不会分配任何暂存区或将任何暂存区传递给外部函数。
- 如果指定了 SCRATCHPAD ,那么在第一次调用用户定义的函数时,将为要由外部函数使用的暂存区分配内存。 在每次调用用户定义的函数时,都会向外部函数传递一个额外的自变量,该自变量用于对暂存区进行寻址。 暂存区具有以下特征:
- FINAL CALL 或 NO FINAL CALL
- 此可选子句指定是否对外部函数进行最终调用 (以及单独的第一次调用)。 它还控制何时重新初始化暂存区。 如果指定了 NO FINAL CALL ,那么数据库服务器只能对表函数进行三种类型的调用 :open , fetch 和 close。 但是,如果指定了 FINAL CALL ,那么除了打开,访存和关闭外,还可以对表函数进行第一次调用和最后一次调用。
对于外部表函数,无论选择哪个选项,调用类型自变量都是 ALWAYS 存在的。
如果由于中断或事务结束而进行最终调用,那么 UDF 可能不会发出除 CLOSE 游标以外的任何 SQL 语句 (SQLSTATE 38505)。 在这些特殊最终调用情境的
call type
自变量中传递特殊值。不能将 FINAL CALL 与 LANGUAGE CPP 一起指定。
- 不允许并行 或 允许对所有 数据库分区 结果表分布式并行执行
- 指定对于函数的单个引用,是否对函数的调用进行并行化。
- DISALLOW PARALLEL
- 指定在每次调用该函数时,将在单个数据库分区上调用该函数。
- 允许对所有 DATABASE PARTITIONS RESULT TABLE DISTRIBUTED 执行并行执行
- 指定在每次调用函数时,都会在所有数据库分区上调用该函数。 将返回在每个数据库分区上获取的结果集的并集。 该函数不能执行 SQL 语句 (还必须指定 NO SQL 子句)。
- 无 DBINFO 或 DBINFO
- 此可选子句指定是否将数据库服务器已知的特定信息作为附加调用时参数 (DBINFO) 传递给函数 (NO DBINFO)。 缺省值为 NO DBINFO。 LANGUAGE OLE 或 PARAMETER TYLE NPSGENERIC 不支持 DBINFO (SQLSTATE 42613)。如果指定了 DBINFO ,那么会将包含以下信息的结构传递给函数:
- 数据库名称-当前连接的数据库的名称
- 应用程序标识-为与数据库的每个连接建立的唯一应用程序标识
- 应用程序授权标识-应用程序运行时授权标识,而不考虑此函数与应用程序之间的任何嵌套函数
- 代码页-数据库代码页
- 模式名称-不适用于外部表函数
- 表名-不适用于外部表函数
- 列名-不适用于外部表函数
- 数据库版本或发行版-调用函数的数据库服务器的版本,发行版和修改级别
- 平台-服务器的平台类型
- 表函数结果列号-由引用函数的语句使用的结果列号的数组; 此信息使函数能够仅返回必需的列值,而不返回所有列值
- 数据库分区号-在其中调用外部表函数的数据库分区的编号; 在单个数据库分区环境中,此值为 0
- CARDINALITY 整数
- 此可选子句提供函数为优化目的返回的预期行数的估计值。 有效值范围从 0 到 9,223,372,036,854,775,807。
如果未对表函数指定 CARDINALITY 子句,那么假定将有限值作为缺省值; 对于 RUNSTATS 实用程序未收集统计信息的表,将采用相同的值。
警告: 如果函数具有无限基数 (即,如果每次调用函数时都返回一行,并且从不返回
end-of-table
条件) ,那么要求表结束条件正确运行的查询将永不终止,并且必须中断。 此类查询的示例包括那些包含 GROUP BY 或 ORDER BY 子句的查询。 因此,建议不要编写具有无限基数的 UDF。 - TRANSFORM GROUP group-name
- 指示在调用函数时要用于用户定义的结构化类型变换的变换组。 如果函数定义包含用户定义的结构化类型作为参数数据类型,那么需要变换。 如果未指定此子句,那么将使用缺省组名 DB2_FUNCTION 。 如果没有为引用的结构化类型定义指定的 (或缺省值) group-name ,那么会产生错误 (SQLSTATE 42741)。 如果没有为给定的组名和结构化类型定义必需的 FROM SQL 变换函数,那么会产生错误 (SQLSTATE 42744)。
- INHERIT SPECIAL REGISTERS
- 此可选子句指定函数中的可更新专用寄存器将从调用语句的环境继承其初始值。 对于在游标的 SELECT 语句中调用的函数,在打开游标时将从环境继承初始值。 对于在嵌套对象(例如触发器或视图)中调用的例程,将从运行时环境继承初始值(而不是从对象定义继承)。
不会将对专用寄存器的任何更改传递回函数的调用者。
不可更新的专用寄存器(例如,日期时间专用寄存器)反映当前正在执行的语句的属性,因此会设置为它们的缺省值。
- NOT SECURED 或 SECURED
- 指定函数是否被认为对行和列访问控制是安全的。 缺省值为 NOT SECURED。
- NOT SECURED
- 指示该函数未被视为安全函数。 调用函数时,函数的参数不得引用已启用列掩码且为其表激活列级访问控制的列 (SQLSTATE 428HA)。 此规则适用于在语句中任何位置调用的非安全用户定义函数。
- SECURED
- 指示该功能被视为安全功能。 在行许可权或列掩码中引用该函数时,该函数必须是安全的 (SQLSTATE 428H8, SQLCODE -20470)。
- STAY RESIDENT NO
- 指定在函数结束后,为该函数装入的库不会驻留在内存中。 在以下情况下,将会忽略此子句:
- 指定了 NOT FENCED 子句。
- LANGUAGE 选项设置为 JAVA 或 CLR。
规则
- 在分区数据库环境中,不支持在外部用户定义的函数或方法中使用 SQL (SQLSTATE 42997)。
- 只能使用定义为 NO SQL 的例程来定义索引扩展 (SQLSTATE 428F8)。
- 如果该函数允许 SQL ,那么外部程序不得尝试访问任何联合对象 (SQLSTATE 55047)。
- 表访问限制 如果函数定义为 READS SQL DATA ,那么该函数中的任何语句都不能访问正在由调用该函数的语句修改的表 (SQLSTATE 57053)。 例如,假设用户定义的函数 BONUS () 定义为 READS SQL DATA。 如果调用了语句 UPDATE EMPLOYEE SET SALARY = SALARY + 奖金 (EMPNO) ,那么不会从 EMPLOYEE 表中读取函数中的 SQL 语句。
注意
- 为用户定义的函数的参数选择数据类型时,请考虑将影响其输入值的提升规则。 例如,可用作输入值的常量可能具有与期望的数据类型不同的内置数据类型,更重要的是,可能无法提升到期望的数据类型。 根据促销规则,通常建议对参数使用以下数据类型:
- INTEGER 而不是 SMALLINT
- DOUBLE 而不是 REAL
- VARCHAR 而不是 CHAR
- VARGRAPHIC 而不是 GRAPHIC
- 对于跨平台的 UDF 的可移植性,建议使用以下数据类型:
- DOUBLE 或 REAL (而不是 FLOAT)
- DECIMAL 而不是 NUMERIC
- CLOB (或 BLOB) 而不是 LONG VARCHAR
- 创建具有尚不存在的模式名称的函数将导致隐式创建该模式,前提是该语句的授权标识具有 IMPLICIT_SCHEMA 权限。 模式所有者是 SYSIBM。 该模式上的 CREATEIN 特权会授予 PUBLIC。
- 将调用定义为 NOT FENCED 的 JAVA 例程,就像它已定义为 FENCED THREADSAFE 一样。
- 特权: 函数的定义者始终接收对该函数的 EXECUTE 特权 WITH GRANT OPTION 以及删除该函数的权限。 在 SQL 语句中使用该函数时,函数定义者必须对该函数所使用的任何程序包具有 EXECUTE 特权,或者对包含这些程序包的模式具有 EXECUTEIN 特权或 DATAACCESS 权限。
- 缺省值的设置: 使用缺省值定义的函数的参数在调用函数时设置为其缺省值,但仅当没有为相应的自变量提供值时,或者在调用函数时指定为 DEFAULT 时,才会设置为其缺省值。
- 语法替代方法: 为了与此数据库产品的先前版本以及其他数据库产品兼容,支持以下语法替代方法。 这些备用项是非标准的,不应使用。
- 可以指定 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
- 可以指定 DB2GENRL 来代替 DB2GENERAL
接受将下列语法作为缺省行为:- 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 语句可能会失效,因为该安全属性会影响涉及已激活行或列级别访问控制的表的语句的访问路径选择。
- EXTERNAL ACTION 函数: 如果在非最外层选择列表中调用 EXTERNAL ACTION 函数,那么结果不可预测,因为调用该函数的次数将根据所使用的存取方案而有所不同。
示例
- 示例 1: 以下示例注册一个表函数,该表函数用于返回由文本管理系统中每个已知文档的单个文档标识列组成的行。 第一个参数与给定的主题区域匹配,第二个参数包含给定的字符串。
在单个会话的上下文中, UDF 将始终返回同一个表,因此它定义为确定性。 请注意用于定义 DOCMATCH 的输出的 RETURNS 子句。 必须为每个表函数指定 FINAL CALL。 此外,由于表函数不能并行操作,因此添加了 DISALLOW PARALLEL 关键字。 虽然 DOCMATCH 的输出大小是高度可变的,但 CARDINALITY 20 是一个代表值,并且是为了帮助数据库优化器而指定的。
CREATE FUNCTION DOCMATCH (VARCHAR(30), VARCHAR(255)) RETURNS TABLE (DOC_ID CHAR(16)) EXTERNAL NAME '/common/docfuncs/rajiv/udfmatch' LANGUAGE C PARAMETER STYLE SQL NO SQL DETERMINISTIC NO EXTERNAL ACTION NOT FENCED SCRATCHPAD FINAL CALL DISALLOW PARALLEL CARDINALITY 20 - 示例 2: 以下示例注册用于在 Microsoft Exchange 中检索消息头信息和消息的部分消息文本的 OLE 表函数。
CREATE FUNCTION MAIL() RETURNS TABLE (TIMERECEIVED DATE, SUBJECT VARCHAR(15), SIZE INTEGER, TEXT VARCHAR(30)) EXTERNAL NAME 'tfmail.header!list' LANGUAGE OLE PARAMETER STYLE SQL NOT DETERMINISTIC FENCED CALLED ON NULL INPUT SCRATCHPAD FINAL CALL NO SQL EXTERNAL ACTION DISALLOW PARALLEL
