CREATE FUNCTION(SQL 标量、表或行)语句
CREATE FUNCTION (SQL 标量,表或行) 语句用于定义用户定义的 SQL 标量,表或行函数。
标量函数 每次调用时都会返回单个值,并且通常在 SQL 表达式有效的情况下有效。 可以在 FROM 子句中使用 表函数 并返回表。 行函数 可用作变换函数并返回行。
调用
此语句可以嵌入在应用程序中,也可通过动态 SQL 语句来发出。 它是一个可执行语句,仅当 DYNAMICRULES 运行行为对于程序包有效时才能动态编译 (SQLSTATE 42509)。
授权
- 数据库上的 IMPLICIT_SCHEMA 权限 (如果函数的隐式或显式模式名不存在)
- 对模式的 CREATEIN 特权,如果函数的模式名称引用现有模式
- 对模式的 SCHEMAADM 权限 (如果函数的模式名存在)
- DBADM 权限
- 该表、视图或昵称的 CONTROL 特权
- 该表、视图或昵称的 SELECT 特权
- 包含该表、视图或昵称的模式的 SELECTIN 特权
- 包含该表、视图或昵称的模式的 DATAACCESS 权限
- 对于数据库的 DATAACCESS 权限
对于 CREATE FUNCTION 语句中指定的任何表或视图,不考虑 PUBLIC 以外的组特权。
调用函数时,将应用昵称所引用的表或视图的数据源的授权需求。 该连接的授权标识可以映射到不同的远程授权标识。
此语句的授权标识所拥有的特权还必须包括调用函数体中指定的 SQL 语句所需的所有特权。
要替换现有函数,语句的授权标识必须是现有函数的所有者 (SQLSTATE 42501)。
如果指定了 SECURED 选项,那么语句的授权标识必须包含 SECADM 或 CREATE_SECURE_OBJECT 权限 (SQLSTATE 42501)。
语法
- 1 OUT and INOUT are valid only if RETURNS specifies a scalar result and the SQL-function-body is a compound SQL (compiled) statement.
- 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 Valid only for compiled scalar function definition and an inlined table function definition. A compiled scalar function defined as MODIFIES SQL DATA can only be used as the only element on the right side of an assignment statement that is within a compound SQL (compiled) statement.
- 5 Valid only if RETURNS specifies a scalar result (data-type2)
- 6 The following apply to the specification of a compound SQL (compiled) statement: a) Must be used if the parameter data types or returned data types include a row type, array type, or cursor type; b) Must be used if the RETURNS TABLE clause specifies any syntax other than a column-list; c) Not supported if RETURNS ROW is specified; d) Not supported when defining a table function in a partitioned database environment.
描述
- OR REPLACE
- 指定替换当前服务器上存在的函数的定义。 在目录中替换新定义之前,现有定义将被有效删除,但授予函数的权限不受影响。 此选项只能由对象所有者指定。 如果函数的定义在当前服务器上不存在,那么忽略此选项。 要替换现有函数,新定义的特定名称和函数名必须与旧定义的特定名称和函数名相同,或者新定义的特征符必须与旧定义的特征符匹配。 否则,将创建新函数。
如果在行许可权或列掩码的定义中引用了该函数,那么无法替换该函数 (SQLSTATE 42893)。
函数名 - 命名要定义的函数。 它是指定函数的限定名称或非限定名称。 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-声明, ...) - 标识函数的输入参数个数,并指定每个参数的模式、名称、数据类型和可选的缺省值。 必须为函数期望接收的每个参数指定列表中的一个条目。 不允许超过 90 个参数 (SQLSTATE 54023)。可以注册一个没有参数的函数。 在这种情况下,仍必须对括号进行编码,并且中间不插入数据类型。 例如:
CREATE FUNCTION WOOFER() ...对于所有相应参数,不允许模式中的两个同名函数具有完全相同的类型。 此类型比较中不考虑长度、精度和比例。 因此, CHAR (8) 和 CHAR (35) 被视为与 DECIMAL (11, $TAG2) 和 DECIMAL (4, $TAG3) 以及 DECFLOAT (16) 和 DECFLOAT (34) 相同的类型。 为参数指定的弱类型单值类型被视为与单值类型的源类型相同的数据类型。 对于 Unicode 数据库,CHAR(13) 和 GRAPHIC (8) 被认为是同一类型。 还有一些类型的进一步捆绑会导致它们被视为用于此目的的相同类型,例如 DECIMAL 和 NUMERIC。 重复签名返回错误 (SQLSTATE 42723)。
如果参数的数据类型是布尔数据类型,数组类型,游标类型或行类型,那么 SQL 函数主体只能引用复合 SQL (已编译) 语句中的参数 (SQLSTATE 428H2)。
- in | out | inout
- 指定参数的模式。 如果函数返回错误,那么未定义 OUT 参数,并且 INOUT 参数保持不变。 缺省值为 IN。
- IN
- 将参数标识为函数的输入参数。 当返回控制时,对函数中的参数所作的任何更改都不可用于调用上下文。 OUT
- 将参数标识为函数的输出参数。 INOUT
- 将参数标识为函数的输入和输出参数。
参数名 - 指定参数的名称。 该名称不能与参数列表中的任何其他 parameter-name 相同 (SQLSTATE 42734)。 data-type1
- 指定参数的数据类型。
- 内置类型
- 指定内置数据类型。 要获取每个内置数据类型的更完整描述 (BOOLEAN 和 CURSOR 除外,不能为表指定) ,请参阅
创建表
。- 布尔值
- 适用于布尔型。
- CURSOR
- 表示对基础游标的引用。
- anchored-data-type
- 标识另一个用于定义参数数据类型的对象。 锚点对象的数据类型可以是作为 data-type1显式允许的任何数据类型。 锚点对象的数据类型的限制与直接指定数据类型或在使用行的情况下创建行类型时的限制相同。
- ANCHOR DATA TYPE TO
- 指示使用锚定数据类型来指定数据类型。
- variable-name1
- 标识全局变量。 全局变量的数据类型将用作 parameter-name 的数据类型。 table-name.column-name
- 标识现有表或视图的列名。 列的数据类型将用作 parameter-name 的数据类型。
- ROW OF table-name 或 view-name
- 根据 table-name 标识的表的列名和列数据类型或 view-name标识的视图,指定具有名称和数据类型的字段行。 参数名 的数据类型 是未命名的行类型。
- ROW OF 游标变量名
- 指定名称和数据类型的字段,这些字段基于 cursor-variable-name 标识的游标变量的字段名和字段数据类型。 指定的游标变量必须是以下元素之一 (SQLSTATE 428HS):
- 具有强类型游标数据类型的全局变量
- 具有弱类型游标数据类型的全局变量,该数据类型是通过使用 CONSTANT 子句指定已命名所有结果列的 select-statement 来创建或声明。
- array-type-name
- 指定用户定义数组类型的名称。 如果在不指定模式名称的情况下指定 array-type-name,那么将通过在 SQL 路径中搜索模式来解析该数组类型。
- cursor-type-name
- 指定游标类型的名称。 如果指定了 cursor-type-name 而没有指定模式名,那么通过在 SQL 路径中搜索模式来解析游标类型。
- distinct-type-name
- 指定单值类型的名称。 该参数的长度、精度和小数位数分别是单值类型的源类型的长度、精度和小数位数。 将单值类型参数作为单值类型的源类型传递。 如果在未指定模式名的情况下指定了 distinct-type-name,那么通过在 SQL 路径中搜索模式来解析单值类型。
- REF (type-name)
- 指定没有作用域的引用类型。 指定的 type-name 必须标识用户定义的结构化类型 (SQLSTATE 428DP)。 系统不会尝试推断参数或结果的作用域。 在函数的主体内部,只有通过首先将其强制转换为具有作用域,才能在取消引用操作中使用引用类型。 同样, SQL 函数返回的引用只能通过首先将其强制转换为具有作用域来在取消引用操作中使用。 如果指定了类型名而没有指定模式名,那么通过在 SQL 路径中搜索模式来解析 type-name。
- row-type-name
- 指定用户定义的行类型的名称。 该参数的字段是行类型的字段。 如果指定了 row-type-name 而没有指定模式名,那么通过在 SQL 路径中搜索模式来解析行类型。
- structured-type-name
- 指定用户定义的结构化类型的名称。 如果指定了没有模式名称的 structured-type-name ,那么将通过在 SQL 路径中搜索模式来解析结构化类型。
- 指定内置数据类型。 要获取每个内置数据类型的更完整描述 (BOOLEAN 和 CURSOR 除外,不能为表指定) ,请参阅
- 缺省值
- 指定参数的缺省值。 缺省值可以是常量,专用寄存器,全局变量,表达式或关键字 NULL。 可以指定为缺省值的专用寄存器与可以为列缺省值指定的专用寄存器相同 (请参阅 CREATE TABLE 语句中的 default-clause )。 通过使用表达式,可以指定其他专用寄存器作为缺省值。
表达式可以是 "表达式" 中描述的任何类型的表达式。 如果未指定缺省值,那么该参数没有缺省值,并且调用该过程时不得省略相应的自变量。 表达式 的最大大小为 64K 字节。
缺省表达式不得修改 SQL 数据(SQLSTATE 428FL 或 SQLSTATE 429BL)。 该表达式必须与参数数据类型赋值兼容 (SQLSTATE 42821)。
在下列情况下,不得指定缺省值:- 对于 INOUT 或 OUT 参数 (SQLSTATE 42601)
- 对于 ARRAY、ROW 或 CURSOR 类型的参数 (SQLSTATE 429BB)
- 对于还指定了 RETURNS ROW 或 PREDICATES 子句的函数定义的参数 (SQLSTATE 42613)
- 指定参数的模式。 如果函数返回错误,那么未定义 OUT 参数,并且 INOUT 参数保持不变。 缺省值为 IN。
- 退货
- 此必需子句标识函数的输出类型。
如果函数输出的数据类型是布尔数据类型,数组类型,游标类型或行类型,那么 SQL 函数主体必须是复合 SQL (编译型) 语句 (SQLSTATE 428H2)。
- data-type2
- 指定输出的数据类型。
在此语句中,适用于先前在 data-type1 中针对函数参数描述的 SQL 函数的参数的注意事项完全相同。
- ROW
- 指定函数的输出为单行。 如果该函数返回多行,那么将返回错误 (SQLSTATE 21505)。这种形式的行函数只能用作结构化类型的变换函数 (具有一个结构化类型作为其参数并仅返回内置数据类型)。
- 列列表
- 为 ROW 函数返回的列名和数据类型的列表。 column-list 必须至少包含两列 (SQLSTATE 428F0)。
- 列名称
- 指定此列的名称。 不能对名称进行限定,并且不能将同一名称用于列表中的多个列。 data-type3
- 指定列的数据类型,并且可以是 SQL 函数的参数支持的任何数据类型。
对于函数参数,与先前在 data-type1 中描述的 SQL 函数参数相同。 但是, data-type3 不支持 anchor-data-type, array-type-name, cursor-type-name和 row-type-name。
- 为 ROW 函数返回的列名和数据类型的列表。 column-list 必须至少包含两列 (SQLSTATE 428F0)。
- 表
- 指定函数的输出是表。
- 列列表
- 为 TABLE 函数返回的列名和数据类型的列表
- 列名称
- 指定此列的名称。 不能对名称进行限定,并且不能将同一名称用于列表中的多个列。 data-type3
- 指定列的数据类型,并且可以是 SQL 函数的参数支持的任何数据类型。
对于函数参数,与先前在 data-type1 中描述的 SQL 函数参数相同。 但是, data-type3 不支持 anchor-data-type, array-type-name, cursor-type-name和 row-type-name。
row-type-name - 指定用于从中派生列列表的字段的行类型。 行类型的字段名称用作列名。
- anchored-row-data-type
- 标识要用作所返回表的列的另一个对象中的行信息。
- ANCHOR DATA TYPE TO
- 指示使用锚定数据类型来指定数据类型。 variable-name
- 标识全局变量。 所引用变量的数据类型必须是行类型。
- ROW OF table-name 或 view-name
- 根据 table-name 标识的表的列名和列数据类型或 view-name标识的视图,指定具有名称和数据类型的字段行。 锚点对象列的数据类型具有适用于 data-type3的相同限制。
- ROW OF 游标变量名
- 指定名称和数据类型的字段,这些字段基于 cursor-variable-name 标识的游标变量的字段名和字段数据类型。 指定的游标变量必须是下列其中一个对象 (SQLSTATE 428HS):
- 具有强类型游标数据类型的全局变量。
- 具有弱类型游标数据类型的全局变量,它是使用 CONSTANT 子句(指定了用于指定所有结果列的 select-statement)创建或声明的。
- array-type-name 的元素
- 指定用于派生列列表的元素数据类型的数组类型。 如果 array-type-name 标识具有行类型的元素的数组类型,那么行类型的字段名称将用作列名。 如果 array-type-name 标识具有非行类型元素的数组类型,那么单个结果列名为 COLUMN_VALUE。
- 为 TABLE 函数返回的列名和数据类型的列表
- 指定输出的数据类型。
- built-in-type
- 请参阅 "CREATE TABLE" 以获取内置数据类型的描述。
- SPECIFIC 具体名称
- 为要定义的函数实例提供唯一名称。 对此函数执行 source、删除或注释时,可以使用此特定名称。 它不能用来调用函数。 非限定格式的
specific-name 是 SQL 标识。 限定格式为 schema-name
后跟句点和 SQL 标识。 该名称 (包括隐式或显式限定符) 不得标识应用程序服务器上存在的另一个函数实例; 否则将发生错误 (SQLSTATE 42710)。
specific-name 可能与现有 function-name相同。
如果未指定限定符,那么将使用用于 function-name 的限定符。 如果指定了限定符,那么它必须与 function-name 的显式或隐式限定符相同,否则将发生错误 (SQLSTATE 42882)。
如果未指定 specific-name,那么数据库管理器会生成唯一名称。 唯一名称是 SQL 后跟字符时间戳记,即 SQLyymmddhhmmssxxx。
- LANGUAGE SQL
- 指定使用 SQL 编写函数。
- PARAMETER CCSID
- 指定要用于所有传入和传入函数的字符串数据的编码方案。 如果未指定
PARAMETER CCSID 子句,那么缺省值为 PARAMETER CCSID UNICODE(对于 Unicode 数据库)和
PARAMETER CCSID ASCII(对于所有其他数据库)。
- ASCII
- 指定字符串数据以数据库代码页编码。 如果该数据库是 Unicode 数据库,那么不能指定 PARAMETER CCSID ASCII (SQLSTATE 56031)。
- UNICODE
- 指定字符数据采用 UTF-8 格式,而图形数据采用 UCS-2 格式。 如果数据库不是 Unicode 数据库,那么不能指定 PARAMETER CCSID UNICODE (SQLSTATE 56031)。
- DETERMINISTIC 或 NOT DETERMINISTIC
- 此可选子句指定函数是否始终对给定的参数值返回相同的结果 (DETERMINISTIC),或者函数是否依赖于影响结果的某些状态值 (NOT DETERMINISTIC)。 即,确定性函数必须始终从具有相同输入的连续调用返回相同的表。 通过指定 NOT DETERMINISTIC 可以防止利用相同输入总是产生相同结果这一事实的优化。
- EXTERNAL ACTION 或 NO EXTERNAL ACTION
- 指定函数是否执行操作来更改数据库管理器不管理的对象的状态。 外部操作的一个示例是发送消息或将记录写入文件。 缺省值为 EXTERNAL ACTION。
- EXTERNAL ACTION
- 指定该函数执行更改数据库管理器不管理的对象的状态的操作。
- NO EXTERNAL ACTION
- 指定函数不执行任何更改数据库管理器不管理的对象的状态的操作。 数据库管理器在优化 SQL 语句期间使用此信息。
- 读取 SQL 数据,包含 SQL 或修改 SQL 数据
- 指定函数可以运行的 SQL 语句的分类。 数据库管理器验证函数问题的 SQL 语句是否与此规范一致。
有关每个语句的分类,请参阅 可在例程和触发器中执行的 SQL 语句。
- READS SQL DATA
- 指定函数可以运行数据访问分类为 READS SQL DATA , CONTAINS SQL 或 NO SQL 的语句。 该函数无法运行修改数据的 SQL 语句 (SQLSTATE 42985)。 这是缺省值。
- CONTAINS SQL
- 指定该函数只能运行数据访问分类为 CONTAINS SQL的 SQL 语句。 该函数无法运行任何读取或修改数据的 SQL 语句 (SQLSTATE 42985)。
- MODIFIES SQL DATA
- 指定该函数可以运行任何 SQL 语句,但在任何函数中不支持的那些语句除外。
- ALLOW PARALLEL 或 DISALLOW PARALLEL
- 此子句指定是否可以并行化 UDF ,即, UDF 的单个调用是否会导致 UDF 的多个实例 (通常每个分区一个实例) 并行运行。 并行化通常会提高整体性能,但仅当满足以下所有条件时才允许:
- 指定了 CONTAINS SQL 子句。
- UDF 的所有调用都完全相互独立。
DISALLOW PARALLEL 是缺省值。
- 静态分派
- 此可选子句指示在函数解析时,将根据函数的参数的静态类型 (声明类型) 来选择函数。
- CALLED ON NULL INPUT
- 此子句指示无论函数的任何自变量是否为空,都将调用该函数。 它可以返回空值或非空值。 测试空参数值的责任在于用户定义的函数。
可以使用短语 NULL CALL 来代替 CALL ON NULL INPUT。
- INHERIT SPECIAL REGISTERS
- 此可选子句指示函数中的可更新专用寄存器将从调用语句的环境继承其初始值。 对于在游标的 SELECT 语句中调用的函数,在打开游标时将从环境继承初始值。 对于在嵌套对象 (例如,触发器或视图) 中调用的例程,将从运行时环境 (而不是对象定义) 继承初始值。
不会将对专用寄存器的任何更改传递回函数的调用者。
某些专用寄存器 (例如 datetime 专用寄存器) 反映了当前正在执行的语句的属性,因此从不从调用者继承。
- 谓词
- 对于使用此函数的谓词,此子句标识那些可以利用索引扩展的谓词,并且可以将可选的选择性子句用于谓词的搜索条件。 如果指定了 PREDICATES 子句,那么必须将该函数定义为具有 NO EXTERNAL ACTION 的确定性函数 (SQLSTATE 42613)。 如果指定了 PREDICATES 子句,并且数据库不是 UNICODE 数据库,那么不得指定 PARAMETER CCSID UNICODE (SQLSTATE 42613)。 如果 SQL-function-body 是 复合 SQL (编译型) 语句 (SQLSTATE 42613) ,那么不能指定 PREDICATES。
- 谓词-规范
- 有关谓词规范的详细信息,请参阅
CREATE FUNCTION (External Scalar)
。
- 有关谓词规范的详细信息,请参阅
- INHERIT ISOLATION LEVEL WITHOUT LOCK REQUEST 或 INHERIT ISOLATION LEVEL WITH LOCK REQUEST
- 指定当函数继承调用该函数的语句的隔离级别时,是否可以将锁定请求与该语句的隔离子句相关联。 缺省值为 INHERIT ISOLATION LEVEL WITHOUT LOCK REQUEST。
- INHERIT ISOLATION LEVEL WITHOUT LOCK REQUEST
- 指定当函数继承调用语句的隔离级别时,不能在 SQL 语句的上下文中调用该函数,该 SQL 语句包含作为指定隔离子句一部分的 lock-request-子句 (SQLSTATE 42601)。
- INHERIT ISOLATION LEVEL WITH LOCK REQUEST
- 指定当函数继承调用语句的隔离级别时,它还继承指定的 lock-request-子句。
- SQL 函数正文
- 指定函数的主体。 可以在 SQL-function-body 中引用参数名称。 可以使用函数名来限定参数名,以避免不明确的引用。
对于 RETURN 语句,请参阅 :RETURN 语句。
对于 复合 SQL (已编译),请参阅: 复合 SQL (已编译) 语句。
对于 复合 SQL (内联),请参阅: 复合 SQL (内联) 语句。
- NOT SECURED 或 SECURED
- 指定函数是否被认为对行和列访问控制是安全的。 缺省值为 NOT SECURED。
- NOT SECURED
- 指示该函数未被视为安全函数。 调用函数时,函数的参数不得引用已启用列掩码且为其表激活列级访问控制的列 (SQLSTATE 428HA)。 此规则适用于在语句中任何位置调用的非安全用户定义函数。
- SECURED
- 指示该功能被视为安全功能。 在行权限或列掩码中引用该函数时,该函数必须是安全的 (SQLSTATE 428H8)。
规则
- 使用锚定数据类型:锚定数据类型不能引用以下对象 (SQLSTATE 428HS):昵称、类型化表、类型化视图、与基于表达式的索引关联的统计视图、声明的临时表、与弱类型游标关联的行定义、具有与数据库代码页或数据库排序规则不同的代码页或排序规则的对象。
- 使用游标类型和行类型: 将游标类型或行类型用于参数或返回游标类型或行类型的函数只能从 复合 SQL (编译型) 语句中调用 (SQLSTATE 428H2)。
- 表访问限制: 如果函数定义为 READS SQL DATA ,那么函数中的任何语句都不能访问由调用该函数的语句修改的表 (SQLSTATE 57053)。 例如,假设用户定义的函数 BONUS () 定义为 READS SQL DATA。 如果调用语句 UPDATE EMPLOYEE SET SALARY = SALARY + 奖金 (EMPNO) ,那么不会从 EMPLOYEE 表中读取函数中的 SQL 语句。
如果使用 MODIFIED SQL DATA 定义的函数包含嵌套的 CALL 语句,那么不允许对由该函数 (通过函数定义或调用该函数的语句) 修改的表进行读访问 (SQLSTATE 57053)。
- 在分区数据库环境中使用:
- 在分区数据库环境中,只能在赋值语句的右侧引用使用定义为 MODISQL 的复合 SQL (编译型) 语句定义的标量函数,并且该函数引用不能是表达式的一部分。 这样的赋值语句不能在复合 SQL (内联) 语句中。
- 在分区数据库环境中,使用定义为 CONTAINS SQL 的复合 SQL (编译型) 语句定义的标量函数受到其他限制: 不需要执行显式语句,并且必须支持所有过程逻辑,而不需要执行 SQL 语句。
- 在分区数据库环境中,使用定义为 READS SQL 的复合 SQL (编译型) 语句定义的标量函数始终强制在协调程序代理程序中运行。 它也不能在 UPDATE 或 DELETE 语句的上下文中使用。
注意
- 解析函数主体中的函数调用是根据对 CREATE FUNCTION 语句有效的 SQL 路径完成的,并且在创建函数后不会更改。
- 如果 SQL 函数包含对任何日期或时间专用寄存器的多个引用,那么所有引用都将返回相同的值,并且将是调用该函数的语句中的寄存器调用返回的相同值。
- SQL 函数的主体不能包含对自身的递归调用,也不能包含对调用它的另一个函数或方法的递归调用,因为无法调用此类函数。
- 如果 SQL 函数主体中引用的对象不存在或被标记为无效,或者定义程序暂时没有访问该对象的特权,并且如果数据库配置参数 auto_reval 未设置为 DISABLED ,那么仍将成功创建 SQL 函数。 SQL 函数将被标记为无效,并将在下次调用时重新生效。
- 以下规则由创建函数或方法的所有语句强制实施:
- 函数可能与方法具有不同的特征符 (将函数的第一个 参数类型 与方法的 主题类型 进行比较)。
- 函数和方法可能未处于覆盖关系。 即,如果函数是将其第一个参数作为主体的方法,那么它不得覆盖或被另一个方法覆盖。 有关覆盖方法的更多信息,请参阅
CREATE TYPE (Structured)
语句。 - 因为覆盖不适用于函数,所以允许两个函数存在,以便如果它们是方法,那么一个函数将覆盖另一个函数。
为了比较上述规则中的参数类型:- 将忽略参数名称,长度, AS LOCATOR 和 FOR BIT DATA。
- 子类型被视为与其超类型不同。
- 特权: 函数的定义者始终接收对该函数的 EXECUTE 特权以及删除该函数的权限。 如果定义者在定义函数所需的所有特权上都具有 WITH GRANT OPTION ,或者定义者具有 SYSADM 或 DBADM 权限,那么还会在该函数上为该函数的定义者提供 WITH GRANT OPTION。
仅当创建函数时从中派生的特权存在时,函数的定义者才会获取特权。 定义者必须直接拥有这些特权,或者因为 PUBLIC 拥有这些特权而拥有这些特权。 不考虑函数定义者所属的组所拥有的特权。 使用该函数时,连接的用户的授权标识必须对昵称在数据源处引用的表或视图具有有效特权。
- 缺省值的设置: 使用缺省值定义的函数的参数在调用函数时设置为其缺省值,但仅当没有为相应自变量提供值时,或者在调用函数时指定为 DEFAULT 时,才会设置为其缺省值。
- EXTERNAL ACTION 函数: 如果在非最外层选择列表中调用 EXTERNAL ACTION 函数,那么结果不可预测,因为调用该函数的次数将根据所使用的存取方案而有所不同。
- 创建安全函数: 通常,具有 SECADM 权限的用户没有创建数据库对象 (例如,触发器或函数) 的特权。 通常,他们将检查该函数访问的数据,确保其安全,然后将 CREATE_SECURE_OBJECT 权限授予当前具有创建安全用户定义的函数所需的特权的人员。 创建函数后,它们将撤销函数所有者的 CREATE_SECURE_OBJECT 权限。
SECURED 属性被认为是一种断言,用于声明用户已为用户定义函数的所有更改建立了更改控制审计过程。 数据库管理器假定所有后续 ALTER FUNCTION 语句或对外部包的更改都存在这样的控制审计过程。
- 在安全函数中调用其他用户定义的函数: 如果安全用户定义的函数调用其他用户定义的函数,那么数据库管理器不会验证这些嵌套的用户定义的函数是否具有 SECURE 属性。 如果这些嵌套函数可以访问敏感数据,那么具有 SECADM 权限的用户需要确保允许这些函数访问这些数据,并且已经为这些函数的所有更改建立了更改控制审计过程。
- 替换现有函数以使安全属性更改 (从 SECURE 更改为 NOT SECURE ,反之亦然): 依赖于该函数的程序包和动态高速缓存的 SQL 语句可能会失效,因为安全属性会影响对涉及激活了行或列级别访问控制的表的语句的访问路径选择。
- 重新绑定从属程序包: 每个已编译的 SQL 函数都有一个从属程序包。 可以随时使用 REBIND_ROUTINE_PACKAGE 过程来重新绑定程序包。 显式地重新绑定从属包不会重新验证无效函数。 使用自动重新验证或使用 ADMIN_REVALIDATE_DB_OBJECTS 过程显式地重新验证无效函数。 函数重新验证会自动重新绑定从属包。
- 语法替代方法: 为了与先前版本的 Db2® 和其他数据库产品兼容,支持以下语法替代方法。 这些替代方法是非标准的,不应使用:
- 可以指定 NULL CALL 来代替 CALL ON NULL INPUT
接受将下列语法作为缺省行为:- Unicode 数据库中的 CCSID UNICODE
- 非 Unicode 数据库中的 CCSID ASCII
示例
- 示例 1: 定义使用现有正弦和余弦函数返回值正切的标量函数。
CREATE FUNCTION TAN (X DOUBLE) RETURNS DOUBLE LANGUAGE SQL CONTAINS SQL NO EXTERNAL ACTION DETERMINISTIC RETURN SIN(X)/COS(X) - 示例 2: 定义结构化类型 PERSON 的变换函数。
CREATE FUNCTION FROMPERSON (P PERSON) RETURNS ROW (NAME VARCHAR(10), FIRSTNAME VARCHAR(10)) LANGUAGE SQL CONTAINS SQL NO EXTERNAL ACTION DETERMINISTIC RETURN VALUES (P..NAME, P..FIRSTNAME) - 示例 3: 定义用于返回指定部门编号中的员工的表函数。
CREATE FUNCTION DEPTEMPLOYEES (DEPTNO CHAR(3)) RETURNS TABLE (EMPNO CHAR(6), LASTNAME VARCHAR(15), FIRSTNAME VARCHAR(12)) LANGUAGE SQL READS SQL DATA NO EXTERNAL ACTION DETERMINISTIC RETURN SELECT EMPNO, LASTNAME, FIRSTNME FROM EMPLOYEE WHERE EMPLOYEE.WORKDEPT = DEPTEMPLOYEES.DEPTNO - 示例 4: 通过审计从示例 3 定义表函数。
CREATE FUNCTION DEPTEMPLOYEES (DEPTNO CHAR(3)) RETURNS TABLE (EMPNO CHAR(6), LASTNAME VARCHAR(15), FIRSTNAME VARCHAR(12)) LANGUAGE SQL MODIFIES SQL DATA NO EXTERNAL ACTION DETERMINISTIC BEGIN ATOMIC INSERT INTO AUDIT VALUES (USER, 'Table: EMPLOYEE Prd: DEPTNO = ' CONCAT DEPTNO); RETURN SELECT EMPNO, LASTNAME, FIRSTNME FROM EMPLOYEE WHERE EMPLOYEE.WORKDEPT = DEPTEMPLOYEES.DEPTNO END - 示例 5: 定义用于反转字符串的标量函数。
CREATE FUNCTION REVERSE(INSTR VARCHAR(4000)) RETURNS VARCHAR(4000) DETERMINISTIC NO EXTERNAL ACTION CONTAINS SQL BEGIN ATOMIC DECLARE REVSTR, RESTSTR VARCHAR(4000) DEFAULT ''; DECLARE LEN INT; IF INSTR IS NULL THEN RETURN NULL; END IF; SET (RESTSTR, LEN) = (INSTR, LENGTH(INSTR)); WHILE LEN > 0 DO SET (REVSTR, RESTSTR, LEN) = (SUBSTR(RESTSTR, 1, 1) CONCAT REVSTR, SUBSTR(RESTSTR, 2, LEN - 1), LEN - 1); END WHILE; RETURN REVSTR; END - 示例 6: 创建用于递增作为 INOUT 参数传递的变量的函数,并将任何错误作为返回码返回。
CREATE FUNCTION increment(INOUT result INTEGER, IN delta INTEGER) RETURNS INTEGER BEGIN DECLARE code INTEGER DEFAULT 0; DECLARE SQLCODE INTEGER; DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN SET code = SQLCODE; RETURN code; END; SET result = result + delta; RETURN code; END@ - 示例 7: 创建将 XML 文档作为输入并返回客户名称的编译型 SQL 函数。
CREATE FUNCTION get_customer_name_compiled(doc XML) RETURNS VARCHAR(25) BEGIN RETURN XMLCAST(XMLQUERY ('$d/customerinfo/name' PASSING doc AS "d")AS VARCHAR(25)); END - 示例 8: 创建一个已编译的 SQL 函数,该函数采用作为 IN 参数传递的电话号码和区域号,并在 OUT XML 参数中返回完整数字。
CREATE FUNCTION construct_xml_phone (IN phoneNo VARCHAR(20), IN regionNo VARCHAR(8), OUT full_phone_xml XML) RETURNS VARCHAR(28) LANGUAGE SQL NO EXTERNAL ACTION BEGIN SET full_phone_xml = XMLELEMENT (NAME "phone", regionNo || phoneNo); RETURN regionNo || phoneNo; END
