外部函数
审查状态
从这一节开始,到这一章末尾的所有部分都正在等待技术和编辑审查。
外部函数,也称为"用户定义函数"(Udf) 是用外部语言编写的程序,且存储在动态加载库中。一旦声明到数据库,它们会成为可用的
在动态和程序语句中,好像他们是在 SQL 语言中内部实现的。
外部函数大幅扩展了SQL处理数据的可能性。使一个函数数据库中可用,它使用DECLARE EXTERNAL FUNCTON语句来声明。
到,它是使用语句声明外部功能声明的。
被加载的库包含一个函数被调用时的所有功能。
注释
外部函数可能被包含在超过一个库或模组中,因为它在语法中被引用。
声明外部函数DECLARE EXTERNAL FUNCTION
作用: 声明一个用户自定函数到数据库
用于: DSQL, ESQL
语法:
DECLARE EXTERNAL FUNCTION funcname
[<arg_type_decl> [, <arg_type_decl> ...]]
RETURNS {
sqltype [BY {DESCRIPTOR | VALUE}] |
CSTRING(length) |
PARAMETER param_num }
[FREE_IT]
ENTRY_POINT 'entry_point' MODULE_NAME 'library_name';
<arg_type_decl> ::=
sqltype [{BY DESCRIPTOR} | NULL] |
CSTRING(length) [NULL]
表 5.27. DECLARE EXTERNAL FUNCTION 语句参数
参数 | 描述 |
uncname | 在数据库中的函数名称。它可能包括达 31 个字符。它应该是唯一的在数据库中的所有内部和外部函数名称中 |
entry_point | 导出函数的名称 |
library_name | 模块的名称(从中导出函数的MODULE_NAME。这将是文件的名称,不包含".dll"或".so"的文件扩展名。 |
sqltype | SQL 数据类型。它不能是数组或数组元素 |
length | 以字节为单位指定 null 终止字符串的最大长度 |
param_num | 输入参数,在声明的输入参数列表中编号从1开始,描述了将该函数所返回的数据类型 |
DECLARE EXTERNAL FUNCTION语句使得用户自定义函数在数据库中用效,UDF声明必须要在每个将要使用的数据库做。那些永远不需要用的数据库就没有必要声明。
外部函数名称在所有函数名称中必须是唯一的。它可能是不同的导出函数名称,作为ENTRY_POINT中指定的参数。
DECLARE EXTERNAL FUNCTION 输入参数
函数数据输入参数跟随在函数的名称之后,用逗号做分隔。每个参数有一个指定的SQL数据类型。数组不能用作函数参数。以及
SQL类型,CSTRING类型是有效的,指定一个以null结尾的字符串带上LENGTH字节的最大长度。
默认情况下,输入参数以引用的方式传递。BY DESCRIPTOR子句可以用来指定替代,如果输入参数是通过描述符。由描述符传递一个参数使它可以处理NULL值。
子句和关键字
RETURNS 子句:(必修的)由函数指定被返回的输出参数。一个函数是标量:它返回一个且仅一个参数。输出参数可以是任何SQL类型(除了一个数组或一个数组元素)或一个以null结尾的字符串(CSTRING)。输出参数可以通过引用传递(默认),通过描述符或值。如果由BY DESCRIPTOR子句被指定,输出参数通过描述符传递。如果由BY VALUE子句指定,输出参数通过值传递。
PARAMETER关键字:从参数param_num下面编号函数返回值,它是很有必要的,如果需要返回一个数据类型BLOB的值。
FREE_IT 关键字:意味着分配用于存储返回值的内存将被释放在函数被执行后。它仅被使用如果内存在 UDF 中被动态分配。在这种 UDF中,内存必须借助ib_util 模块的ib_util_malloc 函数 ,要求函数使用在Firebird中的编码同在传输UDF模块中的的编码对于分配和释放内存兼容.
ENTRY_POINT 子句:指定入口点的名称(导入的函数的名称),作为模块出口。
MODULE_NAME 子句: 定义了块导出的函数名称所在模块。链接到模块不应是完整路径和文件扩展名, 到如果能避免。如果该模块位于默认位置 (在Firebird服务器根目录的子目录.../ UDF 中) 或显式配置的位置在 firebird.conf,它使不同平台之间移动数据库更容易。在firebird.conf 文件中的UDFAccess参数允许外部函数模块的访问限制到进行配置。
任何用户连接到数据库可以声明外部函数 (UDF)。
例子使用 DECLARE EXTERNAL FUNCTION:
1.声明addDate外部函数位于fbudf模组.输入和输出参数是通过引用传递.
DECLARE EXTERNAL FUNCTION addDay
TIMESTAMP, INT
RETURNS TIMESTAMP
ENTRY_POINT 'addDay' MODULE_NAME 'fbudf';
2.声明invl外部函数位于fbudf模组.输入和输出参数是通过描述符传递.
DECLARE EXTERNAL FUNCTION invl
INT BY DESCRIPTOR, INT BY DESCRIPTOR
RETURNS INT BY DESCRIPTOR
ENTRY_POINT 'idNvl' MODULE_NAME 'fbudf';
3.声明isLeapYear外部函数位于fbudf模组.输入是通过引用传递.而输出参数是通过值传递.
DECLARE EXTERNAL FUNCTION isLeapYear
TIMESTAMP
RETURNS INT BY VALUE
ENTRY_POINT 'isLeapYear' MODULE_NAME 'fbudf';
4.声明i64Truncate外部函数位于fbudf模组.输入和输出参数是通过描述符传递.函数的第二个参数被用作返回值.
DECLARE EXTERNAL FUNCTION i64Truncate
NUMERIC(18) BY DESCRIPTOR, NUMERIC(18) BY DESCRIPTOR
RETURNS PARAMETER 2
ENTRY_POINT 'fbtruncate' MODULE_NAME 'fbudf';
参阅: ALTER EXTERNAL FUNCTION, DROP EXTERNAL FUNCTION