比较 IBM DB2 和 IBM solidDB SQL 过程,第 1 部分: 比较结构、参数、变量、赋值、过程体、游标和动态 SQL 语句
简介
本系列文章比较了 IBM DB2 9.5 SQL 过程语言(也称为 SQL PL)与 IBM solidDB 6.3 SQL 过程语言。DB2 和 solidDB 过程都经过一次编译和解析,然后存储到数据库中供日后执行。尽管这两种语言之间存在一定的相似性,但是也有一些比较显著的差别。
第 1 部分
SQL 过程的结构
参数和调用 SQL 过程
SQL 过程的变量和赋值
SQL 过程的过程体
SQL 过程的游标
动态 SQL 过程
第 2 部分
SQL 过程的条件语句
SQL 过程的循环语句
SQL 过程的错误处理
SQL 过程的返回结果集
有关 SQL 过程的其他内容
SQL 过程中的结构
本节介绍 DB2 和 solidDB SQL 过程在结构方面的差异。
DB2 SQL 过程的结构
DB2 SQL 过程的核心是一个复合语句(compound statement)。复合语句也称为复合块(compound block),所绑定的关键字为 BEGIN 和 END。清单 1 解释了 DB2 SQL 过程的结构化格式。
清单 1. DB2 SQL 过程的结构化格式
CREATE PROCEDURE procedure_name (parameters)
LANGUAGE SQL
BEGIN
Local variable declarations
Condition declarations
Cursor declarations
Condition handler declarations
Procedural body
Assignment,
flow of control,
looping
SQL statements
cursors
BEGIN
…
END
Other compound statements either nested or serially placed
END
SQL 过程可以包含一个或多个复合块。这些块可以被嵌套或顺序排列在 SQL 过程中。对于每一个块,对变量、条件和处理程序声明都有一个指定的顺序。这些声明必须位于 SQL 过程逻辑说明的前面。然而,游标可以在 SQL 过程体中的任何位置声明。
有两种类型的复合语句(块):原子性(atomic)和非原子性。
原子性复合语句可以看作是过程中的一个单个工作单元。如果该块中的任何语句失败,那么执行到该失败点的任何语句都将被认为是失败的,并且所有语句都将被执行回滚。换句话说,块中的语句要么全部成功,要不就全部失败。COMMIT、SAVEPOINT 和 ROLLBACK 语句是不允许的。这些语句只在非原子性 块中受支持。
非原子性语句块是默认的类型。即使块内的某个语句失败,其他语句可能会成功并被提交(或回滚),只要工作被显式提交(在过程内或过程所属的工作单元内)。
清单 2 展示了 ATOMIC 和 NOT ATOMIC 块的语法。
清单 2. 原子性和非原子性语句
BEGIN ATOMIC
… procedure code…
END
BEGIN NOT ATOMIC
…procedure code…
END
solidDB 过程的结构
和 DB2 过程一样,solidDB 过程也包含若干部分。包括参数部分、用于本地变量的声明部分和过程体部分。清单 3 展示了 solidDB 过程的格式。
清单 3. solidDB 过程的格式
"CREATE PROCEDURE procedure_name (parameter_section)
BEGIN
declare_section_local_variables
procedure_body
assignment
flow of control
looping
cursor processing
error handling statements
END";
您可以找出一些不同的地方。和 DB2 不同,solidDB 过程并没有包含多个复合语句块。相反,只在过程的开始和结束处包含了一对 BEGIN 和 END 关键字。
solidDB 过程需要将完整的定义部分放到一对双引号之中。
solidDB 过程中的事务可以在过程内部或过程外部提交或回滚。当 solidDB 过程返回到具有 autocommit on 的调用应用程序时(JDBC 或 ODBC),除非指定了回滚,否则将隐式地提交过程。
在过程内部,提交或回滚语句(以及所有其他 SQL 语句)的前面都要使用关键字 EXEC SQL。这与 DB2 SQL 过程不同,后者不需要在 SQL 语句前面使用 EXEC SQL 关键字。清单 4 展示了一个 solidDB 语法的示例。
清单 4. solidDB 语法要求使用 EXEC SQL
EXEC SQL COMMIT WORK;
EXEC SQL ROLLBACK WORK;
和 DB2 相同的是,可以在过程中的任意位置声明 游标,而本地变量必须声明部分中声明,声明部分在 BEGIN 之后过程逻辑之前。
参数和调用 SQL 过程
本节描述 DB2 和 solidDB SQL 过程在参数方面的不同之处。
DB2 过程的参数
参数用于将标量值传递给过程或从过程中传出。DB2 还可以以数组的方式将多组值作为单个参数传递。对于标量值,有三种类型的参数:IN、INOUT 和 OUT。清单 5 展示了一个使用所有三种类型的参数创建过程的示例。参数 p1、p2 和 p3 都各自被声明为 INTEGER(INT)。
清单 5. 使用不同 DB2 参数创建过程
CREATE PROCEDURE proc_name (IN p1 INT, INOUT p2 INT, OUT p3 INT)
LANGUAGE SQL
BEGIN
….
END@
除了 OUT 和 INOUT 参数外,DB2 还向调用程序返回结果集(包括多个行和多个列)。然而,结果集并不是使用 CREATE PROCEDURE 语句中的参数返回的。
solidDB 过程的参数
和 DB2 过程一样,solidDB 过程也有三种类型的参数:IN、OUT 和 INOUT。如果没有指定参数类型,那么默认情况下使用 IN 类型。清单 6 展示了使用 solidDB 语法的示例。
清单 6. 使用不同的 solidDB 参数创建过程
"CREATE PROCEDURE proc_name(p1 INTEGER = 8, OUT p3 INTEGER, INOUT p2 INTEGER)
BEGIN
…
END"
在过程内,输入和输出参数被作为逻辑变量处理。在参数列表中可以为 solidDB 参数指定一个默认值,如清单 6 所示。DB2 不支持在参数列表中初始化变量。
在调用为参数定义了默认值的过程时,不需要指定参数。比如,如果 proc_name 中的所有参数都指定了默认值,那么就可以使用 call proc_name; 调用命令。
您可以在调用过程时通过使用等号(=)为参数赋值,如清单 7 所示。
清单 7. 为参数赋值
call proc_name (p1 = 8, p2, p3);
该命令将参数 p1 的值指定为 8,并为参数 p2 和 p3 指定默认值。如果参数名未在调用语句中使用,solidDB 将假设参数的顺序与 CREATE PROCEDURE 语句中的参数顺序一样。
在 solidDB 中返回值的另一种方法是通过 CREATE PROCEDURE 语句的 RETURNS 子句。RETURNS 子句一般情况下会返回一个结果集表,或者仅返回输出值。这种方法不同于 DB2 中返回结果集所使用的方法,本系列 第 2 部分 将对此加以描述。
SQL 过程的变量和赋值
本节描述 DB2 和 solidDB SQL 过程在变量和赋值方面的区别。
DB2 过程的变量和赋值
SQL 语句用于声明变量并为变量赋值。下面是一些与变量有关的语句类型:
DECLARE <variable_name datatype>
DECLARE <condition>
DECLARE <condition handler>
DECLARE CURSOR <cursor_name> FOR <SQL statement>
SET (assignment-statement)
DB2 过程中的本地变量使用 DECLARE 语句定义。此外,通过使用 DEFAULT 关键字和 DECLARE 语句,变量可以被初始化为默认值。DEFAULT 关键字在 solidDB 中不受 DECLARE 语句的支持。
通过 SET 语句执行赋值。
solidDB 过程中的变量和赋值
在 solidDB 中声明本地变量和赋值的语法与 DB2 相似:DECLARE <variable_name datatype> 。清单 8 展示了一个例子。
清单 8. 在 solidDB 上声明一个本地变量
"CREATE PROCEDURE …. (parameter list)
BEGIN
DECLARE i INTEGER;
DECLARE dat DATE;
END";
所有变量默认情况下被初始化为 NULL。要在 solidDB 中为变量赋值,可以使用 SET variable_name = expression;,或者可以使用 variable_name := expression;。清单 9 展示了一个例子。
清单 9. 在 solidDB 为变量赋值
SET i = i + 20;
i := 100;
表 1 展示了 DB2 中与 solidDB 对应的各种赋值方法。
表 1. 赋值方法概述
DB2 | solidDB | 解释 |
DECLARE v_total INTEGER DEFAULT 0; | DECLARE v_total INTEGER; SET v_total = 0; or v_total := 0; | DEFAULT 和 DECLARE 不受 solidDB 支持 |
SET v_total = v_total + 1; | SET v_total = v_total + 1; or v_total := v_total + 1; | |
SELECT MAX(salary) INTO v_max FROM employee; | EXEC SQL c1 INTO (v_max) EXECDIRECT SELECT MAX(salary) FROM employee; EXEC SQL CLOSE c1; EXEC SQL DROP c1; | 要映射到 solidDB 需要使用游标 |
VALUES CURRENT_DATE INTO v_date; | SET v_date = {fn CURDATE()}; or v_date :=
|