级别: 中级
IBM
2002 年 6 月
本文提供有关复合 SQL 块以及如何使用它们的信息。另外,本文还提供了一个样本来使用。
复合 SQL 赋予程序员将几条 SQL 语句组合成一个可执行块的能力。这很有益处,因为尽管可以分开执行这些语句,但是将它们作为一个块来执行可以减少数据库管理器开销。如果您正在运行远程客户机,那么通过使用复合 SQL 可以减少网络流量。
调用复合 SQL 语句无需授权;然而,用户必须具有执行块中每一条单独语句所需的适当权限。复合 SQL 语句只能嵌入在应用程序中。不可以动态准备复合 SQL 语句,并且在 REXX 中也不支持它。也不支持非静态行为。块中的每一条语句都应该是自包含的并且不依赖于在块中执行的其它语句。如果要在复合块中包括 COMMIT 语句,则该语句必须是最后一条子语句。它将不包括在 STOP AFTER FIRST 子句的计数中。STOP AFTER FIRST 子句用来仅执行块中指定数目的语句。无论语句是否成功完成,都对语句进行计数。在 BEGIN/END 复合块中不允许有主机语言代码。除了以下之外的所有可执行语句都可以包含在复合 SQL 块中:
CALL FETCH CLOSE OPEN CONNECT PREPARE COMPOUND SQL RELEASE DESCRIBE ROLLBACK DISCONNECT SET CONNECTION EXECUTE IMMEDIATE
复合 SQL 块有两种主要类型:ATOMIC 和 NOT ATOMIC。将复合 SQL 块指定为 ATOMIC 是指如果块中任意一条语句执行失败,则回滚整个复合 SQL 块。这还将回滚任何在该复合 SQL 块的开始之前执行的未提交语句。sqlca.sqlerrd 字段将包含在发生错误之前成功完成的语句数目(尽管在遇到错误时将回滚这些语句)。这有助于确定哪条语句导致了错误的发生。块末尾的 SQLCA 将包含失败语句的 SQLCODE。
如果指定了 NOT ATOMIC,则程序将试图执行所有子语句,而不管前面执行的子语句是否失败。要确定哪些语句成功执行以及哪些语句失败,可使用以下错误结构:
- 第二个 SQLERRD 字段包含失败的语句数目。
- 第三个 SQLERRD 字段包含受影响行的累计行数。
- 第四个 SQLERRD 字段包含成功完成的最后一条语句位置。
- 第五个 SQLERRD 字段是那些由于对所有触发了约束活动的子语句强制执行了参考完整性要求或约束条件而被更新或删除行的累计行数。
另外,SQLERRMC 字段将包含执行失败语句的数目,后面跟有格式为 ssscccc的最多七个符号的标记字符串,其中:
sss— 是导致错误的语句的序数位置
ccccc— 是错误的 SQLSTATE
SQLERRML 字段将为您提供 SQLERRMC 字段的长度以帮助您分析结果。
以下是为在我们的示例中使用而产生的表定义:
CREATE TABLE EMP1 (NAME CHAR(20) NOT NULL, YRS_OF_SVC INTEGER NOT NULL, JOB_DESC CHAR(40), PRIMARY KEY (NAME) ); CREATE TABLE COMP_STATS (NBEMP INTEGER);
以下是为演示 sqlca.sqlerrmc 的用法而创建的触发器:
CREATE TRIGGER ADD_EMPS AFTER INSERT ON EMP1 FOR EACH ROW MODE DB2SQL UPDATE COMP_STATS SET NBEMP = NBEMP + 1;
以下是代码片断和 NOT ATOMIC 复合 SQL 块的结果:
===========================================================
代码片断:
===========================================================
/* clean up tables in case of old data */
EXEC SQL DELETE FROM EMP1;
EXEC SQL DELETE FROM COMP_STATS;
/* initialize nbemp value */
EXEC SQL INSERT INTO COMP_STATS VALUES (0);
EXEC SQL COMMIT;
EXEC SQL BEGIN COMPOUND NOT ATOMIC STATIC
INSERT INTO EMP1 VALUES ('Ben Thompson',6,'Athlete');
INSERT INTO EMP1 VALUES ('Zack Thompson',4,'Scientist');
INSERT INTO EMP1 VALUES ('Linda McCullough',11,'SalesRep');
INSERT INTO EMP1 VALUES ('Ben Thompson',6,'Programmer');
/* 3 statements should fail because of primary key violations */ INSERT INTO EMP1 VALUES ('Ben Thompson',6,'Programmer');
INSERT INTO EMP1 VALUES ('Hannah Kap',7,'Writer');
INSERT INTO EMP1 VALUES ('Pauline Kap',3,'Actress');
INSERT INTO EMP1 VALUES ('Ben Thompson',6,'Programmer');/* statement should fail */
COMMIT;
END COMPOUND;
printf("\n\nThe number of rows affected in total by the compound is: %d\n",sqlca.sqlerrd[2]);
printf("Length of sqlerrmc is %d\n",sqlca.sqlerrml);
printf("The number of errors that occurred - ");
/* initialize i to traverse the string */
i=0;
printf("%3.3s\n",&sqlca.sqlerrmc[i]);
/* advance over the "number of errors" position */
i = i+4;
for (i=i;i < sqlca.sqlerrml ;i++ ) {
printf("Statement ordinal position - %3.3s\n",&sqlca.sqlerrmc[i]);
/* advance over the "ordinal position" */
i= i+3;
printf("sqlstate - %5.5s\n",&sqlca.sqlerrmc[i]);
/* advance over the "sqlstate position
上一篇教程: 违背关系誓约
下一篇教程: 您的 opaque 类型可以使用内置散列吗?






