DB2开发系列之三——SQL函数
1、内置函数分类(SYSIBM模式内)
1)标量函数:返回一个标量值的函数;
2)聚合函数:也叫列函数,也返回一个标量值,这个值是一组输入值的计算结果;
3)表函数:向引用它的 SQL 语句返回一个表;
4)行函数:返回单一表行;
2、用户定义的函数
1)有源(或模板)函数:有源函数是从一个已经向数据库注册的函数(称为源函数)构造出的 UDF。有源函数在本质上可以是标量、列或表函数,还可以用它们覆盖 +、-、* 和 / 等操作符。
--语法
CREATE FUNCTION [FunctionName] ( <<[ParameterName]> [InputDataType] ,...> )
RETURNS [OutputDataType]
<SPECIFIC [SpecificName]>
SOURCE [SourceFunction] <([DataType] ,...)>
<AS TEMPLATE>
--示例
CREATE FUNCTION AVG(YEAR) RETURNS YEAR
SOURCE SYSIBM.AVG(INTEGER)
2)SQL 标量、表或行函数:SQL 函数是只使用过程式 SQL 语句构造的 UDF。
--语法
CREATE FUNCTION [FunctionName] ( <<[ParameterName]> [InputDataType] ,...> )
RETURNS [[OutputDataType] |
TABLE ( [ColumnName] [ColumnDataType] ,... ) |
ROW ( [ColumnName] [ColumnDataType] ,... )]
<SPECIFIC [SpecificName]>
<LANGUAGE SQL>
<DETERMINISTIC | NOT DETERMINISTIC>
<EXTERNAL ACTION | NO EXTERNAL ACTION>
<CONTAINS SQL | READS SQL DATA | MODIFIES SQL DATA>
<STATIC DISPATCH>
<CALLED ON NULL INPUT>
[SQLStatements] | RETURN [ReturnStatement]
--示例
CREATE FUNCTION julian_date(in_date DATE)
RETURNS CHAR(7)
LANGUAGE SQL
RETURN RTRIM(CHAR(YEAR(in_date))) ||
SUBSTR(DIGITS(DAYOFYEAR(in_date)), 8)
3)外部标量函数:外部标量函数是用 C、C++ 或 Java™ 等高级编程语言编写的返回单一值的函数。
--创建外部函数的步骤
i)使用支持的高级编程语言编写 UDF 体。
ii)编译 UDF。
iii)链接 UDF 以创建库(或动态链接库)。
iv)调试 UDF 并重复第 2 到第 4 步,直到解决所有问题。
v)把包含 UDF 的库存储在服务器工作站上。另外,必须修改包含 UDF 的库文件的系统权限,让所有用户都可以执行它。例如,在 UNIX 环境中,使用chmod
命令让一个 文件可由所有用户执行;在 Windows 环境中,使用attrib
完成此任务。
vi)使用适当形式的 CREATE FUNCTION
SQL 语句向 DB2 数据库注册 UDF。
--语法
CREATE FUNCTION [FunctionName] ( <<[ParameterName]> [InputDataType] ,...> )
RETURNS [OutputDataType]
<SPECIFIC [SpecificName]>
EXTERNAL <NAME [ExternalName] | [Identifier]>
LANGUAGE [C | JAVA | CLR | OLE]
PARAMETER STYLE [DB2GENERAL | JAVA | SQL]
<DETERMINISTIC | NOT DETERMINISTIC>
<FENCED | NOT FENCED>
<RETURNS NULL ON NULL INPUT | CALLED ON NULL INPUT>
<NO SQL | CONTAINS SQL | READS SQL DATA>
<STATIC DISPATCH>
<EXTERNAL ACTION | NO EXTERNAL ACTION>
<SCRATCHPAD <[100 | [SPSize]]> | NO SCRATCHPAD>
<DBINFO | NO DBINFO>
--示例
CREATE FUNCTION center(INT, DOUBLE)
RETURNS DOUBLE
EXTERNAL NAME '/home/db2inst1/myfuncs/double'
LANGUAGE C
PARAMETER STYLE SQL
DETERMINISTIC
NO SQL
4)外部表函数:与外部标量函数一样,外部表函数是用高级编程语言编写的。外部标量函数返回一个标量值,而外部表函数在每次调用时返回一个数据集。外部表函数的强大之处在于,它们能够让几乎任何数据源看起来像是 DB2 基表。
--语法
CREATE FUNCTION [FunctionName] ( <<[ParameterName]> [InputDataType] ,...> )
RETURNS TABLE ( [ColumnName] [ColumnDataType] ,... )
<SPECIFIC [SpecificName]>
EXTERNAL <NAME [ExternalName] | [Identifier]>
LANGUAGE [C | JAVA | CLR | OLE]
PARAMETER STYLE [DB2GENERAL | SQL]
<DETERMINISTIC | NOT DETERMINISTIC>
<FENCED | NOT FENCED>
<RETURNS NULL ON NULL INPUT | CALLED ON NULL INPUT>
<NO SQL | CONTAINS SQL | READS SQL DATA>
<STATIC DISPATCH>
<EXTERNAL ACTION | NO EXTERNAL ACTION>
<SCRATCHPAD <[100 | [SPSize]]> | NO SCRATCHPAD>
<DBINFO | NO DBINFO>
--示例
CREATE FUNCTION empdata (VARCHAR(30), VARCHAR(255))
RETURNS TABLE (empid INT, lname CHAR(20), fname CHAR(20))
EXTERNAL NAME '/home/db2inst1/myfuncs/EMPDATA'
LANGUAGE C
PARAMETER STYLE SQL
DETERMINISTIC
NOT FENCED
NO SQL
NO EXTERNAL ACTION
5)OLE DB 外部表函数:Microsoft OLE DB 是一组应用程序编程接口 (API),用于访问各种数据源。数据源由数据本身、相关联的数据库管理系统 (DBMS)、运行 DBMS 的平台以及用来访问此平台的网络组成。OLE DB 可以为 OLE Component Object Model (COM) 环境中的所有数据源类型提供访问。
--语法
CREATE FUNCTION [FunctionName] ( <<[ParameterName]> [InputDataType] ,...> )
RETURNS TABLE ( [ColumnName] [ColumnDataType] ,... )
<SPECIFIC [SpecificName]>
EXTERNAL <NAME [ExternalName]>
LANGUAGE OLEDB
<DETERMINISTIC | NOT DETERMINISTIC>
<RETURNS NULL ON NULL INPUT | CALLED ON NULL INPUT>
<EXTERNAL ACTION | NO EXTERNAL ACTION>
<CARDINALITY [NumRows]>
--示例
CREATE FUNCTION orders()
RETURNS TABLE (orderid INTEGER,
customerid CHAR(5),
employeeid INTEGER,
orderdate TIMESTAMP,
requiredate TIMESTAMP,
shipdate TIMESTAMP,
shipcharges DECIMAL(19,4))
LANGUAGE OLEDB
EXTERNAL NAME '!orders!Provider=Microsoft.Jet.OLEDB.3.51;
Data Source=c:\sqllib\samples\oledb\nwind.mdb'
3、SQL函数的结构
1)组成部分
i)函数名
ii)一系列参数声明(如果有参数的话)
iii)函数返回值的声明
iv)一个或多个函数选项
v)函数体
2)结构示意图
3)SQL函数中可以使用的SQL语句
SQL 语句 | CONTAINS SQL | READS SQL DATA | MODIFIES SQL DATA |
---|---|---|---|
CALL | Yes | Yes | Yes |
DELETE | No | No | Yes |
FOR | Yes | Yes | Yes |
GET DIAGNOSTICS | Yes | Yes | Yes |
IF | Yes | Yes | Yes |
INSERT | No | No | Yes |
ITERATE | Yes | Yes | Yes |
LEAVE | Yes | Yes | Yes |
MERGE | No | No | Yes |
SELECT | No | Yes | Yes |
SET variable | Yes | Yes | Yes |
SIGNAL | Yes | Yes | Yes |
VALUES | No | Yes | Yes |
WHILE | Yes | Yes | Yes |
4)单语句 SQL 标量函数
--无参数单语句SQL标量函数
--有参数单语句SQL标量函数
5)单语句 SQL 表函数
--无参数单语句SQL表函数
--有参数单语句SQL表函数
6)复合语句 SQL 标量函数
--无参数复合语句SQL标量函数
--有参数复合语句SQL标量函数
7)复合语句 SQL 表函数
--没参数复合语句SQL表函数
--有参数复合语句SQL表函数
8)SQL Procedural Language (SQL PL) 语句
--与变量相关的语句
i)DECLARE [Variable] DEFAULT [Value]
ii)DECLARE [Condition]
iii)SET (assignment-statement)
--条件语句
i)IF
--循环语句
i)FOR
ii)WHILE
--控制转移语句
i)CALL
ii)ITERATE
iii)LEAVE
iiii)RETURN
--错误管理语句
i)SIGNAL
ii)示例(包含SQL PL语句的SQL标量函数)
9)SQL 函数中的错误处理
--语法
SIGNAL [Condition_Value]
SET MESSAGE_TEXT = [Message]
或
SIGNAL SQLSTATE <VALUE> [SQLSTATE_Value]
SET MESSAGE_TEXT = [Message]
--示例(包含流控制语句的SQL标量函数)
4、调用 SQL 函数
VALUES sqlfunc.strip_ltblanks(' This is a test. ')
,
或
SELECT * FROM TABLE(sqlfunc.bday_this_month('A00'))
----------------------------------------------------------
《高性能SQL调优精要与案例解析》
blog1:http://www.cnblogs.com/lhdz_bj
blog2:http://blog.itpub.net/8484829
blog3:http://blog.csdn.net/tuning_optmization