内联 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 过程可能更适合传递结果集或其他更高级过程元素。