内联 SQL 函数、触发器和复合 SQL 语句
可在复合 SQL(编译型)语句、复合 SQL(内联型)语句、SQL 函数和触发器中执行内联 SQL PL 语句。
复合 SQL(内联型)语句是允许您将多个 SQL 语句组合成可选原子块的语句,可在原子块中声明变量及条件处理元素。这些语句由 Db2® 编译为单个 SQL 语句,并且可包含内联 SQL PL 语句。
SQL 函数和触发器的主体可包含复合 SQL(内联型)语句,并且还可包括一些内联 SQL PL 语句。
复合 SQL(内联型)语句本身在创建简短脚本时很有用,这些脚本用于执行控制流很小但数据流很大的小型逻辑工作单元。在函数和触发器中,它们允许使用这些对象时执行更复杂的逻辑。
考虑以下包含 SQL PL 的复合 SQL(内联型)语句示例:
BEGIN ATOMIC
FOR row AS
SELECT pk, c1, discretize(c1) AS v FROM source
DO
IF row.v is NULL THEN
INSERT INTO except VALUES(row.pk, row.c1);
ELSE
INSERT INTO target VALUES(row.pk, row.d);
END IF;
END FOR;
END复合 SQL(内联型)语句由关键字 BEGIN 和 END 绑定。它包括使用包含在 SQL PL 中的 FOR 和 IF/ELSE
控制语句。FOR 语句用于通过已定义的一组行迭代。对于每行,将检查列值并根据该值有条件地将一组值插入到另一个表中。考虑以下包含 SQL PL 的触发器示例:
CREATE TRIGGER validate_sched
NO CASCADE BEFORE INSERT ON c1_sched
FOR EACH ROW
MODE DB2SQL
Vs: BEGIN ATOMIC
IF (n.ending IS NULL) THEN
SET n.ending = n.starting + 1 HOUR;
END IF;
IF (n.ending > '21:00') THEN
SIGNAL SQLSTATE '80000' SET MESSAGE_TEXT =
'Class ending time is after 9 PM';
ELSE IF (n.DAY=1 or n.DAY-7) THEN
SIGNAL SQLSTATE '80001' SET MESSAGE_TEXT =
'Class cannot be scheduled on a weekend';
END IF;
END vs;此触发器将在对表 c1_sched 执行插入操作时激活,并且会使用 SQL PL
来检查并提供类结束时间(如果尚未提供),如果类结束时间在晚上 9 点以后或者该类安排在周末,那么会产生错误。考虑以下包含 SQL PL 的标量 SQL 函数的示例:
CREATE FUNCTION GetPrice (Vendor CHAR(20), Pid INT)
RETURNS DECIMAL(10,3)
LANGUAGE SQL MODIFIES SQL
BEGIN ATOMIC
DECLARE price DECIMAL(10,3);
IF Vendor = 'Vendor 1'
THEN SET price = (SELECT ProdPrice FROM V1Table WHERE Id = Pid);
ELSE IF Vendor = 'Vendor 2'
THEN SET price = (SELECT Price FROM V2Table WHERE Pid = GetPrice.Pid);
END IF;
RETURN price;
END此简单函数根据标识供应商的输入参数的值返回标量价格值。它还会使用 IF 语句。
对于需要输出参数的较复杂逻辑,SQL 过程可能更适合传递结果集或其他更高级过程元素。