CREATE FUNCTION(SQL 标量)
此 CREATE FUNCTION (SQL 标量) 语句在当前服务器上创建 SQL 函数。 此函数返回单个结果。
调用
此语句可嵌入应用程序中或者以交互方式发出。 它是可以动态准备的可执行语句。
授权
此语句的授权标识所拥有的特权必须至少包括下列其中一项:
- 要在模式中创建的特权。 有关更多信息,请参阅 在模式中创建所需的特权。
- 数据库管理员权限
此语句的授权标识所拥有的特权必须至少包括下列其中一项:
- 对于 SYSFUNCS 目录视图和 SYSPARMS 目录表:
- 对表的 INSERT 特权,以及
- 对模式 QSYS2 的 USAGE 特权
- 数据库管理员权限
语句的授权标识所拥有的特权还必须至少包含下列其中一项:
- 以下系统权限:
- *USE 到 "创建服务程序" (CRTSRVPGM) 命令或
- 数据库管理员权限
如果引用了单值类型,那么语句的授权标识所拥有的特权必须至少包含下列其中一项:
- 对于语句中标识的每个单值类型:
- 单值类型的 USAGE 特权,以及
- 对包含单值类型的模式的 USAGE 特权
- 数据库管理员权限
- 该语句的授权标识必须具有 安全性管理员权限。 请参阅 管理权限 (Administrative authority)。
要替换现有函数,语句的授权标识所拥有的特权必须至少包含下列其中一项:
- 以下系统权限:
与函数相关联的服务程序对象上的 *OBJOPR、*OBJMGT 和 *READ 的系统权限
- DROP 函数所需的所有权限
- 对 SYSFUNCS 目录视图和 SYSPARMS 目录表的系统权限 *READ
- 数据库管理员权限
有关与 SQL 特权对应的系统权限的信息,请参阅 检查对表或视图的特权时的相应系统权限 和 检查对单值类型的特权时的相应系统权限。
语法
描述
- OR REPLACE
- 指定替换当前服务器上存在的函数的定义。 在目录中替换新定义之前,将有效删除现有定义,但对该功能授予的特权不受影响。 如果当前服务器上不存在函数的定义,那么将忽略此选项。 要替换现有函数,新定义的 specific-name 和 function-name 必须与旧定义的 specific-name 和 function-name 相同。 或者新定义的签名必须与旧定义的签名相匹配。 否则,将创建新的函数。
- function-name
- 命名用户定义的函数。 除非指定了 OR REPLACE ,否则名称,模式名称,参数数量和每个参数的数据类型 (不考虑数据类型的任何长度,精度,小数位或 CCSID 属性) 的组合不得标识当前服务器上存在的用户定义的函数。
对于 SQL 命名,将在隐式或显式限定符指定的模式中创建函数。
对于系统命名,将在限定符指定的模式中创建函数。 如果未指定限定符:
- 如果 CURRENT SCHEMA 专用寄存器的值是 *LIBL ,那么将在当前库 (*CURLIB) 中创建该函数。
- 否则,将在当前模式中创建函数。
通常,如果每个函数的函数特征符都是唯一的,那么多个函数可以具有相同的名称。
某些函数名保留供系统使用。 有关详细信息,请参阅 CREATE FUNCTION 中选择模式和函数名称。
- (parameter-声明 ...)
- 指定函数的输入参数数目以及每个参数的数据类型。 每个 参数-声明 指定函数的输入参数。 最多可以指定 2000 个参数。 函数可以具有零个或多个输入参数。 对于函数期望接收的每个参数,列表中必须有一个条目。 函数的所有参数都是可空的输入参数。 有关详细信息,请参阅在 CREATE FUNCTION 中定义参数。
- 参数名称
- 命名参数。 该名称用于引用函数主体中的参数。 名称不能与参数列表中的任何其他 parameter-name 相同。
- data-type1
- 指定输入参数的数据类型。 数据类型可以是内置数据类型或单值数据类型。
- 内置类型
- 指定内置数据类型。 有关每种内置数据类型的更完整说明,请参阅 CREATE TABLE。
- distinct-type-name
- 指定单值类型。 参数的长度,精度或小数位属性是单值类型的源类型 (在 CREATE TYPE 上指定的那些类型) 的属性。 有关创建区分类型的更多信息,请参阅 CREATE TYPE (distinct)。
如果未限定单值类型的名称,那么数据库管理器将通过在 SQL 路径中搜索模式来解析模式名称。
- array-type-name
- 指定数组类型。
如果未限定数组类型的名称,那么数据库管理器将通过在 SQL 路径中搜索模式来解析模式名称。
如果指定了 CCSID ,那么在将该参数传递给该函数之前,该参数将转换为该 CCSID。 如果未指定 CCSID ,那么在调用该函数时, CCSID 由当前服务器上的缺省 CCSID 确定。
作为 XML 或 LOB 类型的数组的参数是只读的。
- default-clause
- 指定参数的缺省值。 默认值可以是常数、特殊寄存器、全局变量、表达式、
a 搜索条件、
或关键字 NULL。 表达式是 Expressions 中定义的任何表达式,不包括聚合函数或列名。
如果指定了 搜索条件,则它不得包含 EXISTS 或 IN 谓词中的子查询。
如果未指定默认值,则该参数没有默认值,在调用时不能省略。 表达式字符串的最大长度为 64K。
缺省表达式必须是与参数数据类型兼容的赋值。
缺省表达式中用作列表中数字常量的分隔符的任何逗号都必须后跟空格。
创建函数时,缺省表达式中引用的所有对象都必须存在。
不能为数组类型的参数指定缺省值。
- 退货
- 指定函数的结果。
- data-type2
- 指定要为函数返回的表达式。 表达式的结果数据类型必须可分配 (使用存储分配规则) 到 RETURNS 子句中定义的数据类型。 有关详细信息,请参阅 分配和比较。
您可以指定任何内置数据类型 (LONG VARCHAR 或 LONG VARGRAPHIC 除外) ,单值类型 或数组类型。
如果指定了 CCSID ,并且以另一 CCSID 对返回数据的 CCSID 进行编码,那么会将数据转换为指定的 CCSID。
如果未指定 CCSID ,那么如果以另一 CCSID 编码返回数据的 CCSID ,那么将返回数据转换为作业的 CCSID (或图形字符串返回值的作业的相关图形 CCSID)。 为了避免在转换期间任何可能的字符丢失,请考虑显式指定可以表示将从函数返回的任何字符的 CCSID。 如果数据类型是图形字符串数据,那么这尤其重要。 在这种情况下,请考虑使用 CCSID 1200 或 13488 (Unicode 图形字符串数据)。
- LANGUAGE SQL
- 指定这是 SQL 函数。
- SPECIFIC specific-name
- 指定函数的唯一名称。 有关特定名称的更多信息,请参阅 CREATE FUNCTION 中为函数指定特定名称。
- 程序名 external-program-name
- 指定要为函数创建的服务程序的非限定名。 external-program-name 必须是有效的系统名称。
- 全局确定性 , 语句确定性 或 非确定性
- 指定每次使用相同的输入自变量调用函数时函数是否返回相同的结果。 缺省值为 NOT 确定性。
- NOT DETERMINISTIC
- 指定每次使用相同的输入参数调用函数时,该函数可能不会返回相同的结果。 该函数依赖于一些影响结果的状态值。 数据库管理器在优化 SQL 语句期间使用此信息。 非确定性函数的一个示例是生成随机数的函数。
如果函数由并行任务执行,那么不确定的函数可能会返回不正确的结果。 为这些函数指定 DISALLOW PARALLEL 子句。
如果函数包含对专用寄存器,非确定性函数或序列的引用,那么应指定非确定性函数。
- 全球确定性
- 指定每次使用相同的输入参数调用函数时,函数总是返回相同的结果。 数据库管理器在优化 SQL 语句期间使用此信息。 查询优化器可以选择高速缓存全局确定性标量函数结果。1 全局确定性函数的一个示例是计算输入自变量的平方根的函数。
- 语句确定性
- 指定每次使用相同的输入自变量调用该函数时,该函数可能不会返回相同的结果,但单个 SQL 语句中对该函数的多次调用被认为是确定性的。 查询优化器将不会对语句确定性标量函数结果进行高速缓存。2 语句确定性函数的一个示例是执行货币转换的函数。
- 外部操作 或 无外部操作
- 指定函数是否执行操作来更改数据库管理器不管理的对象的状态。 外部操作的一个示例是发送消息或将记录写入流文件。 缺省值为 EXTERNAL ACTION。
- EXTERNAL ACTION
- 指定函数可以执行更改数据库管理器不管理的对象的状态的操作。 因此,必须使用每个连续的函数调用来调用该函数。 如果函数包含对具有外部操作的另一个例程的引用,那么应指定 EXTERNAL ACTION。
- NO EXTERNAL ACTION
- 该函数不会执行外部操作。 不需要使用每个连续的函数调用来调用该函数。
NO EXTERNAL ACTION 函数的性能可能优于 EXTERNAL ACTION 函数,因为对于每个连续的函数调用,都可能不会调用这些函数。
- 包含 SQL ,读取 SQL 数据, 或 修改 SQL 数据
- 指定函数可以执行的 SQL 语句 和嵌套例程 的分类。 数据库管理器将验证函数 发出的 SQL 语句以及函数 本地调用的所有例程是否与此规范一致。 调用嵌套远程例程时,不会执行验证。 有关各语句的分类,请参阅 SQL 语句的特征。 缺省值为 READS SQL DATA。 此选项适用于任何参数缺省表达式。
- 读取 SQL 数据
- 指定函数可以执行数据访问分类为 READS SQL DATA , CONTAINS SQL 或 NO SQL 的语句。 该函数无法执行修改数据的 SQL 语句。
- 包含 SQL
- 指定函数只能执行数据访问分类为 CONTAINS SQL 或 NO SQL 的 SQL 语句。 该函数无法执行任何读取或修改数据的 SQL 语句。
- 修改 SQL 数据
- 该函数可以执行任何 SQL 语句,但在任何函数中不受支持的语句除外。
- 在空输入上返回空值 或 在空输入上调用
- 指定当任何输入自变量在执行期间为空时是否调用函数。
- 在输入时返回空值
- 指定如果任何输入自变量为空,那么不调用该函数。 结果值为 NULL。
- CALLED ON NULL INPUT
- 指定如果任何或所有自变量值都为空,那么将调用该函数。 此规范表示必须对函数进行编码以测试空参数值。 该函数可以返回空值或非空值。
WITHOUT RESTRICT ON DROP or WITH RESTRICT ON DROP
指定是否可以放弃函数。 缺省值为 WITHOUT RESTRICT ON DROP。
- 不限制删除
- 指定可以删除该函数。
- 具有对删除的限制
- 指定在除去此属性之前不能删除该函数。
- 继承专用寄存器
- 指定在进入函数时继承专用寄存器的现有值。
- 静态分派
- 指定以静态方式分派函数。 所有功能都以静态方式分派。
- 不允许调试方式,允许调试方式, 或 DISABLE DEBUG MODE
- 指示是否创建了此函数,以便统一调试器可以对其进行调试。 如果指定了 DEBUG MODE ,那么不得在 SET OPTION 语句中指定 DBGVIEW 选项。
- 禁用调试方式
- 此函数无法由统一调试器调试。 当函数的 DEBUG MODE 属性为 DISALLOW 时,可以随后更改该函数以更改 DEBUG MODE 属性。
- 允许调试方式
- 此函数可由统一调试器进行调试。 当函数的 DEBUG MODE 属性为 ALLOW 时,可随后更改该函数以更改调试方式属性。
- 禁用调试方式
- 此函数无法由统一调试器调试。 当函数的 DEBUG MODE 属性为 DISABLE 时,不能随后更改该函数以更改调试方式属性。
如果为该函数指定了 FENCED 或 ALLOW PARALLEL ,那么将忽略 DEBUG MODE 选项。 将使用 DISALLOW DEBUG MODE。
如果未指定 DEBUG MODE ,但指定了 SET OPTION 语句中的 DBGVIEW 选项,那么该函数不能由统一调试器调试,但可以由系统调试设施调试。 如果既未指定 DEBUG MODE ,也未指定 DBGVIEW 选项,那么使用的调试方式来自 CURRENT DEBUG MODE 专用寄存器。
- 受防护 或 未受防护
- 指定 SQL 函数是否在与数据库管理器环境隔离的环境中运行。 FENCED 是缺省值。
- FENCED
- 该函数将在单独的线程中运行。
FENCED 函数无法在对该函数的个别调用中保持 SQL 游标处于打开状态。 但是,一个线程中的游标独立于任何其他线程中的游标,这会降低游标名称冲突的可能性。
- NOT FENCED
- 该函数可以在与调用 SQL 语句相同的线程中运行。
NOT FENCED 函数可以使 SQL 游标在对该函数的各个调用中保持打开状态。 由于游标可以保持打开状态,因此在对函数的调用之间也将保留光标位置。 但是,由于 UDF 现在与调用 SQL 语句和其他 NOT FENCED UDF 在同一线程中运行,因此游标名可能会发生冲突。
NOT FENCED 函数的性能通常优于 FENCED 函数。
- 允许并行 或 不允许并行
- 指定是否可以并行运行函数。
如果指定了以下一个或多个子句,那么缺省值为 DISALLOW PARALLEL: 非确定性,外部操作或修改 SQL 数据。 否则,缺省值为 ALLOW PARALLEL。
- ALLOW PARALLEL
- 指定数据库管理器可以考虑函数的并行性。 数据库管理器不需要对调用该函数的 SQL 语句或从该函数中发出的任何 SQL 语句使用并行性。
请参阅 "非确定性" , "外部操作" 和 "修改 SQL 数据" 的描述,以了解适用于 ALLOW PARALLEL 规范的注意事项。
- DISALLOW PARALLEL
- 指定数据库管理器不得对该函数使用并行性。
- 并发访问权解析
- 指定数据库管理器是否应该等待正处于更新过程中的数据。 DEFAULT 是缺省值。
- DEFAULT
- 指定没有为此函数显式设置并发访问解析。 将使用调用函数时生效的值。
- 等待结果
- 指定数据库管理器在更新过程中等待落实或回滚数据。
- 使用当前落实的数据
- 指定当迂到正在更新的数据时,数据库管理器将使用当前已落实的数据版本。
- 系统时间敏感
- 确定对静态和动态 SQL 语句中的系统周期时态表的引用是否受 CURRENT TEMPORAL SYSTEM_TIME 专用寄存器的值影响。 缺省值为 YES。
- 是
- 对系统周期时态表的引用会受CURRENT TEMPORAL SYSTEM_TIME专用寄存器的值影响。
- 否
- 对系统周期时态表的引用不会受CURRENT TEMPORAL SYSTEM_TIME专用寄存器的值影响。
- 不受保护 或 受保护
- 指定对于行访问控制和列访问控制,是否认为该函数是安全的。
- 不安全
- 指定对于行访问控制和列访问控制,该函数被视为不安全。 这是缺省情况。
- SECURED
- 指定对于行访问控制和列访问控制,该函数被认为是安全的。
- WRAPPED obfuscated-statement-text
- 指定函数的编码定义。 可以使用 WRAP 标量函数对 CREATE FUNCTION 语句进行编码。
- SET OPTION-语句
- 指定将用于创建函数的选项。 这些选项也适用于任何缺省值表达式。 例如,要创建可调试函数,可以包含以下语句:
选项的缺省值取决于创建时生效的选项。 有关 , 的信息,请参阅 SET OPTION。SET OPTION DBGVIEW = *SOURCE
在 CREATE FUNCTION 语句中不允许使用选项 CNULRQD , CNULIGN , COMPILEOPT , NAMING 和 SQLCA。 处理缺省值表达式时使用以下选项 :ALWCPYDTA , CONACC , DATFMT , DATSEP , DECFLTRND ,DECMP, DECRESULT , DFTRDBCOL , LANGID , SQLCURRULE , SQLPATH , SRTSEQ , TGTRLS , TIMFMT 和 TIMSEP。
- SQL 例程主体
- 指定单个 SQL-procedure-statement,包括复合语句。 有关定义 SQL 函数的更多信息,请参阅 SQL 控制语句。
函数中不允许调用发出 CONNECT , SET CONNECTION , RELEASE , DISCONNECT , COMMIT , ROLLBACK 和 SET TRANSACTION 语句的过程。
如果 SQL-routine-body 是复合语句,那么它必须至少包含一个 RETURN 语句,并且在调用该函数时必须执行 RETURN 语句。
ALTER PROCEDURE (SQL) , ALTER FUNCTION (SQL 标量) 和带有 REPLACE 关键字的 ALTER FUNCTION (SQL 表) 在 SQL-routine-body中是不允许的。
注意
定义用户定义函数的一般注意事项:有关定义用户定义函数的一般信息,请参阅 CREATE FUNCTION。
SQL 路径和函数解析: 解析函数主体中的函数调用是根据对 CREATE FUNCTION 语句有效的 SQL 路径完成的,在创建函数后不会更改。
函数所有权: 如果指定了 SQL 名称:
- 如果存在与创建函数的模式同名的用户概要文件,那么该函数的 所有者 就是该用户概要文件。
- 否则,该函数的 所有者 是执行该语句的 线程 的用户概要文件或组用户概要文件。
如果指定了系统名称,那么函数的 owner 是执行该语句的 thread 的用户概要文件或组用户概要文件。
函数权限: 如果使用 SQL 名称,那么将在 *PUBLIC 上使用系统权限 *EXCLUDE 创建函数。 如果使用系统名称,那么将创建具有 *PUBLIC 权限的函数,由模式的创建权限 (CRTAUT) 参数确定。
如果该函数的所有者是组概要文件 (GRPPRF 关键字) 的成员,并且指定了组权限 (GRPAUT 关键字) ,那么该组概要文件也将具有该函数的权限。
- 将废弃任何现有注释或标签。
- 维护授权用户。 对象所有者可以更改。
- 保留当前日志审计。
如果替换了函数并且更改了函数特征符或结果数据类型,那么引用该函数的任何函数,具体化查询表,过程,触发器或视图的结果可能不可预测。 应重新创建任何引用的对象。
创建函数: 创建 SQL 函数时,数据库管理器将创建一个临时源文件,该文件将包含带有嵌入式 SQL 语句的 C 源代码。 然后使用 CRTSRVPGM 命令创建 *SRVPGM 对象。 用于创建服务程序的 SQL 选项是执行 CREATE FUNCTION 语句时生效的选项。 使用 ACTGRP (*CALLER) 创建服务程序。
创建 SQL 函数时,该函数的属性将存储在创建的服务程序对象中。 如果保存了 *SRVPGM 对象,然后将其恢复到此系统或其他系统,那么将使用这些属性来更新目录。
如果提供了 PROGRAM NAME 子句,那么其名称将用于创建服务程序对象。 否则,将使用特定名称来确定源文件成员和 *SRVPGM 对象的名称。 如果特定名称是有效的系统名称,那么它将用作成员和程序的名称。 如果该成员已存在,那么将覆盖该成员。 如果指定的库中已存在程序,那么将使用生成系统表名称的规则来生成唯一名称。 如果特定名称不是有效的系统名称,那么将使用生成系统表名称的规则来生成唯一名称。
调用函数: 调用 SQL 函数时,它将在调用程序的激活组中运行。
如果在 select-statement 的 select-list 中指定了函数,并且该函数指定了 EXTERNAL ACTION 或 MODISQL DATA ,那么将仅对返回的每行调用该函数。 否则,可以对未选择的行调用 UDF。
- SQL 函数是 全局 确定性函数。
- SQL-routine-body 仅包含 RETURN 语句。
- 没有输入参数是数组类型。
- 结果的数据类型不是 XML 或数组类型。
- 创建函数时,该函数中引用的所有对象都存在。
- SQL-routine-body 不包含引用输入参数的公共表表达式。
- SQL-routine-body 不包含没有引用输入参数的前置横向关键字的嵌套表表达式。
- 该查询适用于 SQL Query 引擎 (SQE)。
- 该函数引用了一个对象,并且该函数的权限属性与该查询根据下列其中一个条件兼容:
- 该函数定义为在用户权限 (*USER) 下运行。
- 查询在所有者的权限 (*OWNER) 下运行,并且查询的所有者与函数的所有者相同。
- 查询在用户权限 (*USER) 下运行,用户或用户的组概要文件与功能的所有者相同。
- PARALLEL 或 NOT PARALLEL
- 修改 SQL 数据
- 落实控制级别
- 并发访问权解析
- ALWCPYDTA
- ATatomic 或 NOT ATatomic
如果函数直接插入并且包含对专用寄存器的引用,那么专用寄存器的值将与查询中对同一专用寄存器的其他引用相同。
- SELECT INTO 的 select-list
- DECLARE CURSOR 的 select-list
- SET 语句右侧标量子查询的 select-list
模糊化语句: 可以模糊化形式执行 CREATE FUNCTION 语句。 在模糊化语句中,只有函数名和参数可读取,后跟 WRAPPED 关键字。 该语句的其余部分将以不可读方式进行编码,但支持模糊语句的数据库服务器可以解码该部分。 可以通过调用 WRAP 标量函数来生成模糊化语句。 将忽略从模糊化语句创建函数时指定的任何调试选项。 无法将从模糊化语句创建的函数复原到不支持模糊化的发行版。
设置缺省值: 使用缺省值定义的函数的参数在调用该函数时将设置为其缺省值,但仅当没有为相应的自变量提供值时,或将该自变量指定为 DEFAULT 时。
从属对象: SQL 例程依赖于 SQL-routine-body中引用的对象。 从属对象的名称存储在目录视图 SYSROUTINEDEP 中。 如果 SQL-routine-body 中的对象引用是标准名称,或者在 SQL 命名中,如果未限定的名称由当前模式限定,那么 SYSROUTINEDEP 中对象的模式名称将设置为指定的名称或当前模式的值。 否则,模式名称未设置为特定模式名称。 未限定的函数名,变量名和类型名将具有 CURRENT PATH 模式名。 如果该名称未设置为实际模式名,那么 DROP 和 ALTER 语句将无法确定例程是否依赖于要改变或删除的对象。
语法替代方法: 以下关键字是支持与先前发行版兼容的同义词。 这些关键字是非标准的,不应使用:
- 关键字 VARIANT 和 NOT VARIANT 可用作 NOT 确定性和确定性的同义词。
- 关键字 NULL CALL 和 NOT NULL CALL 可用作 CALL ON NULL INPUT 和 RETURNS NULL ON NULL INPUT 的同义词。
- 关键字 IS 确定性可用作确定性的同义词。
示例
示例 1: 定义使用现有 SIN 和 COS 内置函数返回值正切的标量函数。
CREATE FUNCTION TAN
(X DOUBLE)
RETURNS DOUBLE
LANGUAGE SQL
CONTAINS SQL
NO EXTERNAL ACTION
DETERMINISTIC
RETURN SIN(X)/COS(X)
请注意,为函数 TAN 的输入参数指定了参数名 (X)。 在函数的主体中使用参数名称来引用输入参数。 对 SIN 和 COS 函数的调用,在 TAN 用户定义函数的主体中,传递参数 X 作为输入。
示例 2: 定义一个标量函数,该函数返回格式为 mm/dd/yyyy 的日期,后跟最多 3 个字符的字符串:
CREATE FUNCTION BADPARM
(INP1 DATE,
USA VARCHAR(3))
RETURNS VARCHAR(20)
LANGUAGE SQL
CONTAINS SQL
NO EXTERNAL ACTION
DETERMINISTIC
RETURN CHAR(INP1,USA)CONCAT USA
假定如以下语句中所示调用该函数:
SELECT BADPARM(BIRTHDATE,'ISO')
FROM EMPLOYEE WHERE EMPNO='000010'
结果是 '08/24/1933ISO'. 请注意,为函数 BADPARM 的输入参数指定了参数名称 (INP1 和 USA)。 虽然存在名为 USA 的输入参数,但 CHAR 函数的参数列表中的 USA 实例将用作内置 CHAR 函数的关键字参数,而不是名为 USA 的参数。