SQL 过程的结构
SQL 过程由若干逻辑部分组成,并且 SQL 过程开发要求您根据结构化格式实现这些部分。
该格式非常直观,易于遵循并且旨在简化例程的设计和语义。
SQL 过程的核心是复合语句。复合语句由关键字 BEGIN 和 END 绑定。这些语句可以为 ATOMIC 或 NOT ATOMIC。缺省情况下,它们为 NOT ATOMIC。
label: BEGIN
Variable declarations
Condition declarations
Cursor declarations
Condition handler declarations
Assignment, flow of control, SQL statements and other compound statements
END label
该图显示 SQL 过程可由一个或多个可选 ATOMIC 复合语句(块)组成,并且可在单个 SQL 过程中嵌套或顺序引入这些块。在每个原子块中,可选变量、条件和处理程序声明都有规定顺序。它们必须在引入使用 SQL 控制语句和其他 SQL 语句及游标声明实现的过程逻辑之前。可使用 SQL 过程体中包含的一组 SQL 语句在任意位置声明游标。
为明晰控制流,可像 SQL 过程原子块中包含的许多 SQL 控制语句那样标记这些原子块。这使得您能够轻松地精确引用变量和控制转移语句引用。
CREATE PROCEDURE DEL_INV_FOR_PROD (IN prod INT, OUT err_buffer VARCHAR(128))
LANGUAGE SQL
DYNAMIC RESULT SETS 1
BEGIN
DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
DECLARE SQLCODE integer DEFAULT 0;
DECLARE NO_TABLE CONDITION FOR SQLSTATE '42704';
DECLARE cur1 CURSOR WITH RETURN TO CALLER
FOR SELECT * FROM Inv;
A: BEGIN ATOMIC
DECLARE EXIT HANDLER FOR NO_TABLE
BEGIN
SET ERR_BUFFER='Table Inv does not exist';
END;
SET err_buffer = '';
IF (prod < 200)
DELETE FROM Inv WHERE product = prod;
ELSE IF (prod < 400)
UPDATE Inv SET quantity = 0 WHERE product = prod;
ELSE
UPDATE Inv SET quantity = NULL WHERE product = prod;
END IF;
END A;
B: OPEN cur1;
ENDSQL 过程中的 NOT ATOMIC 复合语句
先前示例说明了 NOT ATOMIC 复合语句,它是 SQL 过程中使用的缺省类型。如果复合语句中发生了未处理的错误情况,那么将不回滚该错误之前完成的所有工作,但也不会落实这些工作。仅当使用 ROLLBACK 或 ROLLBACK TO SAVEPOINT 语句显式回滚工作单元时,才会回滚语句组。还可使用 COMMIT 语句来落实成功语句(如果这样做有用)。
CREATE PROCEDURE not_atomic_proc ()
LANGUAGE SQL
SPECIFIC not_atomic_proc
nap: BEGIN NOT ATOMIC
INSERT INTO c1_sched (class_code, day)
VALUES ('R11:TAA', 1);
SIGNAL SQLSTATE '70000';
INSERT INTO c1_sched (class_code, day)
VALUES ('R22:TBB', 1);
END napSIGNAL 语句执行时,它会显式产生未处理的错误。之后该过程立即返回。过程返回后,尽管发生了错误,但第一个 INSERT 语句仍会成功执行并将一行插入到 c1_sched 表中。该过程既不会落实,也不会回滚行插入操作,这将留待调用该 SQL 过程的完整工作单元完成。
SQL 过程中的 ATOMIC 复合语句
就如名称所示,ATOMIC 复合语句可视为单个整体。如果其中发生任何未处理错误,那么已执行至该点的所有语句也将被视为失败,并因此回滚。
ATOMIC 复合语句不能嵌套在其他 ATOMIC 复合语句中。
不能在 ATOMIC 复合语句中使用 SAVEPOINT 语句、COMMIT 语句或 ROLLBACK 语句。它们仅在 SQL 过程的 NOT ATOMIC 复合语句中受支持。
CREATE PROCEDURE atomic_proc ()
LANGUAGE SQL
SPECIFIC atomic_proc
ap: BEGIN ATOMIC
INSERT INTO c1_sched (class_code, day)
VALUES ('R33:TCC', 1);
SIGNAL SQLSTATE '70000';
INSERT INTO c1_sched (class_code, day)
VALUES ('R44:TDD', 1);
END apSIGNAL 语句执行时,它会显式产生未处理的错误。之后该过程立即返回。尽管成功执行产生的表没有对此过程插入的行,但第一个 INSERT 语句会回滚。
标签和 SQL 过程复合语句
可选择使用标签来命名 SQL 过程中的任何可执行语句,包括复合语句和循环。通过在其他语句中引用标签,可强制执行流跳出命令语句或循环,或者另外跳至复合语句或循环的开头。GOTO、ITERATE 和 LEAVE 语句可引用标签。
可选择对复合语句的 END 提供相应标签。如果已提供结尾标签,那么它必须与用于其开头的标签相同。
每个标签在 SQL 过程的主体中必须唯一。
如果在存储过程的多个复合语句中声明了同名变量,那么还可使用来标签来避免歧义。可使用标签来限定 SQL 变量的名称。