主机DB2数据库应用与编程 任课老师:王湖南 wanghunan@scu.edu.cn 四川大学计算机(软件)学院
第三部分 第八章 COBOL嵌入式应用程序开发 8.1 COBOL嵌入式应用程序开发基本概念 8.1.2 分隔符 8.1.3 宿主变量 8.1.4 DCLGEN 8.1.5 空值的处理 8.1.6 SQLCA 8.2 数据插入样例 8.2.1 DCLGEN工具使用 8.2.2 COBOL源程序 8.2.3 预编译、编译、链接、执行COBOL源程序的JCL 8.2.4 确认执行结果
8.3 单行数据查询样例 8.3.1 COBOL源程序 8.3.2 预编译、编译、链接、执行COBOL源程序的JCL 8.3.3 确认执行结果 8.4含空值处理的单行数据查询样例 8.4.1 COBOL源程序 8.4.2 预编译、编译、链接、执行COBOL源程序的JCL 8.4.3 确认执行结果 8.5 利用游标实现多行数据查询样例 8.5.1 COBOL源程序 8.5.2 预编译、编译、链接、执行COBOL源程序的JCL 8.5.3 确认执行结果 8.6 利用游标实现动态SQL语句样例 8.6.1 COBOL源程序 8.6.2 预编译、编译、链接、执行COBOL源程序的JCL 8.6.3 确认执行结果 8.7 利用不敏感可滚动游标实现多行数据查询样例 8.7.1 创建临时数据库 8.7.2 创建临时表空间 8.7.3 创建全局临时表 8.7.4 COBOL源程序 8.7.5 预编译、编译、链接、执行COBOL源程序的JCL 8.7.6 确认执行结果
8.8 利用敏感静态可滚动游标实现多行数据查询样例 8.8.1 COBOL源程序 8.8.2 预编译、编译、链接、执行COBOL源程序的JCL 8.8.3 确认执行结果 8.9 数据更新样例 8.9.1 COBOL源程序 8.9.2 预编译、编译、链接、执行COBOL源程序的JCL 8.9.3 确认执行结果 8.10 数据删除样例 8.10.1 COBOL源程序 8.10.2 预编译、编译、链接、执行COBOL源程序的JCL 8.10.3 确认执行结果
第八章 嵌入式COBOL程序开发 8.1 COBOL嵌入式应用程序开发基本概念 8.1.1 COBOL嵌入式应用程序开发总体结构图
COBOL嵌入式应用程序开发总体结构图如下: Source file DBRM file Modified Source file Object file Package Plan Executbale file Precompile Bind Package Bind Plan Compile Linkedit Run Command
Precompile
Compile/Link-edit
Bind
在上图中,COBOL嵌入式源程序由COBOL源程序中嵌入DB2 SQL语句组成。用JCL来处理COBOL嵌入式源程序。 第一步预编译后DB2 SQL语句从COBOL源程序中分离,分别生成剔除SQL语句的修改的源程序和包含SQL语句的DBRM文件。 修改的源程序可以看作普通的COBOL源程序,经过通常的编译后生成目标文件,联结后生成可执行文件。 DBRM文件经过两次绑定先后生成包和计划。 运行COBOL嵌入式源程序可以有两种基本方式: 在JCL里运行 在CICS里运行 这些将在下文实例部分详细介绍。
8.1.2 分隔符 嵌入式SQL应用程序的特点如下: 使用分隔符来标识应用程序中的SQL语句。 使用宿主变量来在WHERE子句中提供值,或从SELECT语句中得到值。 使用SQLCA来确认SQL语句是否成功。
预编译器使用分隔符来识别要编译的SQL语句。嵌入式程序开发中应当标识每一句嵌入式SQL语句的开始和结束。 例如:以本文的样例表EMP为例,使用EXEC SQL和END-EXEC来分隔在COBOL程序中的SQL语句如下: EXEC SQL UPDATE EMP SET WORKDEPT = 'C00' WHERE WORKDEPT = 'C01' END-EXEC.
8.1.3 宿主变量 宿主变量用来在语句执行前设置值。SQL语句中的宿主语言标记是在变量前加冒号,且宿主变量应当与数据表列的数据类型匹配。 宿主变量的示例如下图:
有了宿主变量,前面的SQL语句可以改写为: EXEC SQL UPDATE EMP SET WORKDEPT = ‘C00’ WHERE WORKDEPT = :dept END-EXEC. 其中dept是宿主变量,前面用冒号标示,一般由用户在界面(传统界面一般是CICS MAP,也可以是WEB界面)输入,这样修改的值就不仅限于C01了。
INSERT INTO EMP( EMPNO, LASTNAME ) VALUES ( '000100', 'JONES' ) 更完整的嵌入式COBOL程序样例代码 比如单行插入的SQL语句样例如下: INSERT INTO EMP( EMPNO, LASTNAME ) VALUES ( '000100', 'JONES' ) 在COBOL程序中的相关语句及SQL语句如下: MOVE 'JONES' TO NAME. MOVE '000100' TO EMPNO. EXEC SQL INSERT INTO EMP( EMPNO, LASTNAME ) VALUES ( :EMPNO, :NAME ) END-EXEC. 000100 JOINS EMPNO NAME 注意:同样是宿主变量,在SQL语句中的宿主变量EMPNO前面有一个冒号,但是在COBOL MOVE语句中则前面没有冒号。
嵌入式程序开发数据传递机制 一般情况是用户在CICS MAP或WEB界面里输入用户的查询或其他操作的条件,如000100和JONES,然后程序通过一个机制得到这些值(在CICS课程里会详细讲述),程序再做MOVE语句将得到的值传给对应的宿主变量,然后通过EXEC SQL END-EXEC语句,从宿主变量里取值拼接成一个完成的SQL语句,完成数据库操作。如果数据库不需要返回要显示的数据(如INSERT,UPDATE,DELETE语句) ,那么操作结束,如果数据库需要返回数据显示(如SELECT语句),那么返回的数据还会存入宿主变量,通过MOVE语句将宿主变量的值传给要输出显示的变量,然后程序通过一个机制(在CICS课程里会详细讲述)送出这些值到CICS MAP或WEB显示给用户。
宿主变量声明
COBOL程序中宿主变量声明的例子如下: 建表的语句如下: CREATE TABLE EMP 在程序发出SQL语句查询、插入、更新和删除数据之前,应当首先声明程序中所用的表和视图。只要在程序中加入SQL DECLARE语句即可,每个数据表列对应一个宿主变量,同时需要使用额外的变量来指示列为空的情况。 COBOL程序中宿主变量声明的例子如下: 建表的语句如下: CREATE TABLE EMP ( EMPNO CHAR(6) NOT NULL, FIRSTNME VARCHAR(12) NOT NULL, MIDINIT CHAR(1) NOT NULL, LASTNAME VARCHAR(15) NOT NULL, WORKDEPT CHAR(3), PHONENO CHAR(4), HIREDATE DATE, JOB CHAR(8), EDLEVEL SMALLINT, SEX CHAR(1), BIRTHDATE DATE, SALARY DECIMAL(9, 2), BONUS DECIMAL(9, 2), COMM DECIMAL(9, 2) );
对应的COBOL代码如下: DATA DIVISION. WORKING-STORAGE SECTION. EXEC SQL BEGIN DECLARE SECTION END-EXEC. EMPNO CHAR(6) NOT NULL. FIRSTNME VARCHAR(12) NOT NULL. EXEC SQL END DECLARE SECTION END-EXEC. PROCEDURE DIVISION. EXEC SQL SELECT FIRSTNME INTO :FIRSTNME FROM EMP WHERE EMPNO = :EMPNO END-EXEC. 其中EXEC SQL BEGIN DECLARE SECTION END-EXEC. 和 EXEC SQL END DECLARE SECTION END-EXEC.之间为部分宿主变量的申明。由于手工书写宿主变量的申明需要考虑到与数据库相应列的名称,数据类型和长度等对应,过于繁琐,所以我们通常用DCLGEN工具来自动生成宿主变量的申明。
8.1.4 DCLGEN DCLGEN(Declarations Generator)用于自动生成数据表或视图所对应的宿主变量结构,而不用象前面一节手工生成。可以采用DB2I菜单自动生成这个结构(将在案例部分介绍);也可在下图的TSO命令中或JCL中执行如下语句生成该结构。
DCLGEN中表和对应的宿主变量定义示意图如下:
COBOL程序中的SQL INCLUDE语句用于包含DCLGEN声明(也可以包含SQLCA声明,下文介绍)。这样程序开发者就不用手工将DCLGEN自动生成的数据表或视图所对应的宿主变量结构写入COBOL源代码,而只需要将如下简单的语句写入COBOL源代码: EXEC SQL INCLUDE EMP END-EXEC.
程序预编译后生成如下结构:
如果SELECT对应的列是允许为空的情况,那么必须使用指示符变量(NULL INDICATOR,COBOL中数据类型SMALLINT)。 8.1.5 空值的处理 如果SELECT对应的列是允许为空的情况,那么必须使用指示符变量(NULL INDICATOR,COBOL中数据类型SMALLINT)。 如果列的值为空,那么指示符变量设置为负值,原先的宿主变量值不变。 指示符变量可以被程序设置为负值从而在SQL语句中标识空的情况。
8.1.5 空值的处理 使用指示符变量的例子如下: SELECT WORKDEPT INTO :WORKDEPT :WKDPTIND FROM EMP WHERE EMPNO=:EMPNO 其中前面的WORKDEPT是选出来的列,后面的WORKDEPT是通常意义上的宿主变量值,WKDPTIND便是指示符变量。
以下是EMP表(部分)和相应的空指示符的声明: ******************************************************** * COBOL DECLARATION FOR TABLE EMP 01 S-EMP. 10 EMPNO PIC X(6). 10 LASTNAME. 49 LASTNAME-LEN PIC S9(4) USAGE COMP. 49 LASTNAME-TEXT PIC X(15). 10 JOB PIC X(2). 10 WORKDEPT PIC X(3). 10 PHONENO PIC X(4). * INDICATOR VARIABLE STRUCTURE * 01 IEMP. 10 PHONEIND PIC S9(4) USAGE COMP OCCURS 2 TIMES.
COBOL程序中查询语句的空值处理逻辑如下: IF PHONEIND < 0 MOVE 'UNKN' TO PHONENO. COBOL程序中传递空值的处理逻辑如下: IF (some condition) MOVE -1 TO PHONEIND ELSE MOVE 0 TO PHONEIND. EXEC SQL UPDATE EMP SET PHONENO = :PHONENO :PHONEIND WHERE EMPNO = :EMPNO END-EXEC.
8.1.6 SQLCA 执行程序时,每执行一条SQL语句,就返回一个状态符和一些附加信息。这些信息反映了SQL语句的执行情况,它有助于用户分析应用程序的错误所在。这些信息都存放在SQLCA结构中。如果一个源文件中包含SQL语句,则必须要在源程序中定义一个SQLCA结构,而且名为SQLCA。典型的定义方法是在源文件中加入一些语句:EXEC SQL INCLUDE SQLCA END-EXEC.。如前面所述。 COBOL程序中可以用以下语句在COBOL中包含SQLCA结构。 EXEC SQL INCLUDE SQLCA END-EXEC.
程序预编译后生成的SQLCA结构如下:
SQLCA中和应用开发人员联系最紧密的是SQLCODE 和SQLSTATE。 SQLSTATE 通常五个字符,头两个是字符,不如SQLCODE详细,但是不会依赖操作系统平台。 SQLCODE 和SQLSTATE的详细情况如下:
SQLCA中其他一些有用的域: SQLCA中的元素SQLERRD:返回SQL语句影响数据库中表的行数。 SQLWARN*:存放SQL警告信息,包括SQLWARN1- SQLWARN9及SQLWARNA,详细信息参见SQL REFERENCE。
8.2 数据插入样例 首先重置主表DEPT数据并清空子表EMP数据:
8.2.1 DCLGEN工具使用 DCLGEN工具用于自动生成数据库表对应的COBOL数据结构:
生成的数据库表对应的COBOL数据结构如下:
在第一个例子中,通过INSERT语句向样例表中插入数据,将执行成功或失败的消息显示于屏幕
8.2.2 COBOL源程序 COBOL源程序如下:
嵌入式COBOL程序的大体结构(COBOL语言部分将在COBOL程序设计里详细介绍,故略)如下: 首先在WORKING-STORAGE SETION里将SQLCA和EMP表对应的数据结构INCLUDE进来,然后定义一些COBOL变量,然后在PROCEDURE DIVISION里书写各个程序段,如A0000里书写SQL语句,A0011里判段数据库操作是否成功,B1000是当SQLCODE不等于0(即数据库操作不成功)时的处理。
8.2.3 预编译、编译、链接、执行COBOL源程序的JCL
JCL代码说明(假设读者已具有JCL的基本知识): 对照前面的COBOL嵌入式应用程序开发总体结构图,我们可以看出该JCL包含了总体结构图里对应的各个步骤。程序首先在JCLLIB ORDER里指定该JCL要使用的编目过程(CATALOGED PROCEDURE)的路径,在COMLNK1 EXEC里指定该编目过程的名字DSNHCOB,重要的基础代码都在该编目过程。JCL首先将前面已经编写完毕的源文件(在PC.SYSIN的ST001.CF82.SOURCE(DB2SSE)指定)预编译后分离成DBRM文件(在PC.DBRMLIB的ST001.DBRMLIB.DATA(DB2SSE)指定路径名和MEMBER名,该MEMBER名将自动生成)和更改过的源代码(MODIFIED SOURCE CODE,见DSNHCOB里SYSCIN对应的临时文件&&DSNHOUT,系统自动生成)。在预编译时还要用到对应的宿主变量结构的路径(需要事先用DCLGEN等工具生成,见PC.SYSLIB的ST001.CF82.INCLUDE),存放宿主变量结构的MEMBER名在源代码中EXEC SQL INCLUDE EMP END-EXEC.指定。另外在JOBLIB里指定DB2得系统库为DSN810.SDSNLOAD,预编译时要用到库中的程序DSNHPC。
预编译分离完成后,将分成两路,一路将DBRM文件榜定成包和计划(见BIND PACKAGE和BIND PLAN语句,参数略),另一路将更改过的源代码像普通纯COBOL程序一样编译、联结成可执行代码(RUN LOAD MODULE,见LKED.SYSLMOD ST001.RUNLIB.LOAD(DB2SSE),其中DB2SSE是RUN LOAD MODULE的名字,联结成功后由系统自动生成)。最后在JCL里执行该可执行代码,执行时要用到榜定生成的计划(见最后一步SYSTSIN里的RUN PROGRAM(DB2SSE) PLAN(ST001) ),其中DB2SSE是前面步骤生成的RUN LOAD MODULES的名字,ST001是前面榜定生成的计划名,后面的LIBRARY指定RUN LOAD MODULE的路径,可以不加单引号,系统自动补上前缀,也可以加上单引号,用数据集全名。
8.2.4 确认执行结果 确认数据被插入:
8.3 单行数据查询样例 在第二个例子中,通过SELECT语句将样例表中的数据选出一行并显示于屏幕。 8.3.1 COBOL源程序 COBOL源程序如下:
嵌入式COBOL程序说明: 该嵌入式COBOL程序的结构同前一例基本相似,不同之处在于在PROCEDURE DIVISION处多了USING L-NAME,表示程序将接受在JCL里的输入,系统会自动传递给LINKAGE SECTION里定义的变量L-EMPNO-LEN,然后通过MOVE语句传递给宿主变量,然后通过SQL语句访问数据库,选出想要的数据后显示给屏幕.
8.3.2 预编译、编译、链接、执行COBOL源程序的JCL 预编译、编译、链接、执行COBOL源程序的JCL如下,系统参数通过JCL程序提供:
JCL代码说明: 该JCL代码基本同前一例相似,唯一不同是在最后一步SYSTSIN DD里增加一个PARM参数,指定输入的员工号参数是000100。在执行程序时,系统会自动传递给LINKAGE SECTION里定义的变量L-EMPNO-LEN 。
8.3.3 确认执行结果 确认查询结果:
8.4含空值处理的单行数据查询样例 第三个例子仍旧是单行数据查询的样例,但是加入了空值处理,使得可以处理表中的列可空的情况。 首先将EMPNO为000100的行的PHONENO列更改为空值:
应用程序将选择这一行的PHONENO,结果是PHONENO列显示NONE而非空。
8.4.1 COBOL源程序 COBOL源程序如下:
嵌入式COBOL程序说明: 该程序使用了游标(CURSOR,将在下一节讲述游标),在WORKING-STORAGE SECTION里定义空指示符变量,在游标FETCH时使用空指示符变量,如果空指示符变量小于0,那么程序将空指示符变量对应的宿主变量显示为“NONE”或其他字符到屏幕,如果不为0,那么将从数据库中取出的值显示到屏幕。
8.4.2预编译、编译、链接、执行COBOL源程序的JCL 预编译、编译、链接、执行COBOL源程序的JCL如下,系统参数通过JCL程序提供:
JCL同上例结构基本相同。
8.4.3确认执行结果 确认执行结果如下:
8.5 游标的概念和使用 数据库的游标是类似于C语言指针一样的语言结构,通常情况下,数据库执行的大多数命令都是同时处理集合内部的所有数据。但是,有时侯用户也需要对这些数据集合中的每一行进行操作。在没有游标的情况下,这种工作不得不放到数据库前端,用高级语言来实现。这将导致不必要的数据传输,从而延长执行的时间。通过使用游标,可以在服务器端有效地解决这个问题。游标提供了一种在服务器内部处理结果集的方法,它可以识别一个数据集合内部指定的工作行,从而可以有选择地按行采取操作。本文只介绍使用游标最基本和最常用的方法。
1.声明游标 使用游标前要先声明游标。声明游标的语法如下:DECLARE 游标名 [INSENSITIVE] [SCROLL] CURSOR FOR SELECT语句 [FOR READ ONLY|UPDATE[OF 列名1,列名2,列名3…] ] 使用INSENSITIVE参数定义的游标,把提取出来的数据放入一个在叫TEMP的用户临时数据库的临时表里。任何通过这个游标进行的操作,都在这个临时表里进行。所以所有对基本表的改动都不会在用游标进行的操作中体现出来。如果不使用INSENSITIVE参数,那么用户对基本表所做的任何操作,都将在游标中得到体现。 使用SCROLL参数定义的游标,具有包括如下所示的所有取数功能: FIRST 取第一行数据 LAST 取最后一行数据 PRIOR 取前一行数据 NEXT 取后一行数据 RELATIVE 按相对位置取数据 ABSOLUTE 按绝对位置取数据
如果没有在声明时使用SCROLL参数,那么所声明的游标只具有默认的NEXT功能。 READ ONLY声明只读光标,不允许通过只读光标进行数据的更新。 UPDATE[OF 列名1,列名2,列名3…]定义在这个游标里可以更新的列,如果定义了[OF 列名1,列名2,列名3…],那么只有列在表中的列可以被更新,如果没有定义[OF 列名1,列名2,列名3…],那么所有的列都可以被更新。
2.打开游标 在使用游标之前,必须首先打开游标,打开游标的语法很简单: OPEN cursor_name 当执行打开游标的语句时,服务器执行声明的游标时使用的语句,如果使用了INSENSITIVE参数,则服务器会在TEMP数据库中建立一张临时表,以存放游标将要操作的数据集的副本。
3.使用游标取数据 在打开游标后,就可以通过FETCH语句提取游标的数据了。使用游标提取某一行数据的语法如下: FETCH [ [ NEXT | PRIOR | FIRST | LAST | ABSOLUTE N | RELATIVE N ] FROM cursor_name [INTO 宿主变量名列表]
注:在使用INTO子句对变量赋值时,变量的数量和相应的数据类型必须和声明游标时使用的SELECT语句中引用到的数据列的数目、排列顺序和数据类型完全保持一致,否则服务器会提示错误。 通常使用FETCH进行游标取数的操作和COBOL语言中的PERFORM … UNTIL语句结合,每FETCH一次指针就往下移动一行,系统返回的SQLCODE=0。当游标移动到最后一行时,继续执行取下一行数据的操作,将取不到数据,系统将返回SQLCODE=+100的信息。所以可以以SQLCODE<0或SQLCODE=+100为循环终止的条件,进行连续取数。具体样例将在后面介绍。
4.使用游标更新数据 要使用游标进行数据的修改,其前提条件是该游标必须被声明为可更新的游标。在进行游标声明时,没有带READONLY关键字的游标都是可更新的游标。 使用游标更新数据的常用语法如下: UPDATE table_name {SET column_name = expression} [,...n] WHERE column_name = expression WHERE CURRENT OF cursor_name 其中 CURRENT OF cursor_name表示当前游标的当前数据行。CURRENT OF字句只能使用在进行 UPDATE和DELETE操作语句中。具体样例将在后面介绍。
DELETE FROM table_name WHERE CURRENT OF cursor_name 5.使用游标还可以进行数据的删除,语法是: DELETE FROM table_name WHERE CURRENT OF cursor_name 具体样例略。
5.关闭游标 在打开游标后,DB2服务器会专门为游标开辟一定的内存空间存放游标操作的数据结果集,同时游标的使用也会根据具体情况对某些数据进行封锁。所以,在不使用游标时,一定要将其关闭,以通知服务器释放其所占用的资源。 关闭游标的语法如下: CLOSE cursor_name 关闭游标后,可以再次打开游标。在一个事务中,可以多次打开关闭游标。
利用游标实现多行数据查询样例 在第四个例子中,通过定义游标(Cursor)样例表中的数据选出多行并显示于屏幕
8.5.1 COBOL源程序 COBOL源程序如下:
嵌入式COBOL程序说明: 在这个例子中,系统首先声明游标,该游标根据某查询条件从EMP表中选出几列,接着打开游标,然后执行一个循环,用FETCH语句从游标中选择出每一行数据,直到所有数据选择完毕或出错结束。
8.5.2 预编译、编译、链接、执行COBOL源程序的JCL 预编译、编译、链接、执行COBOL源程序的JCL如下,系统参数通过JCL程序提供:
8.5.3 确认执行结果 确认查询结果如下:
8.6 动态SQL语句概念 嵌入式动态 SQL将获取数据的命令(不是数据本身,这一点与静态SQL不同)存入宿主变量中,这些语句将由PREPARE语句在运行时进行预编译。 动态 SQL 需要增加 PREPARE 和 EXECUTE 语句,以便在程序运行期间创建存取路径和执行 SQL 语句。 使用动态SQL的样例如下: EXEC SQL DECLARE C1 CURSOR FOR S1 END-EXEC. EXEC SQL PREPARE S1 FROM :var0 END-EXEC. EXEC SQL EXECUTE S1 USING :var1,:var2 END-EXEC. EXEC SQL OPEN C1 END-EXEC. PERFORM ... UNTIL SQLCODE = +100 OR SQLCODE < 0. EXEC SQL FETCH C1 INTO ... END-EXEC. DISPLAY ... EXEC SQL CLOSE C1 END-EXEC. 其中C1是CURSOR的名字,var0中存放动态SQL语句的主干部分,var1和var2中存放SQL语句需要的参数,可选。
静态SQL语句与动态SQL语句的区别 在实际情况中,绑定包,计划和执行计划可能不是同一用户。 1.对于静态SQL语句来说,绑定包和计划的用户既需要对应的BIND权限,又需要具体SQL语句的权限,而执行计划的用户只需要EXECUTE权限; 对于动态SQL语句来说,绑定包和计划的用户只需要对应的BIND权限,而执行计划的用户既需要EXECUTE权限,又需要具体SQL语句的权限。 2.静态SQL适用于在绑定包和计划与执行计划时间间隔内表数据不频繁更新(包括插入,更新和删除)的情况,而动态SQL适用于该时间间隔内表数据更新频繁的情况。
Dynamic SQL
利用游标实现动态SQL语句样例 在第五个例子中,通过定义游标(Cursor)实现动态SQL语句将样例表中的数据选出多行并显示于屏幕。 8.6.1 COBOL源程序 COBOL源程序如下:
8.6.2 预编译、编译、链接、执行COBOL源程序的JCL
8.6.3 确认执行结果 确认查询结果如下:
8.7 可滚动游标(Scrollable Cursor) 当打开可滚动游标时,游标定义范围内的行将被拷贝到由用户自定义的临时表(declared temporary table)中,这个临时表又叫结果表(result table)。所以在使用可滚动游标时,结果表所在的临时数据库TEMP必须存在。取数据时的前滚和后退作用于结果表而不是源表。当游标关闭时,结果表被DB2自动删除。
敏感和不敏感游标的区别: 不敏感的游标意味着在游标打开后,不能看到其他应用对基础表中的更改(包括数据插入,更新和删除),不敏感的游标是只读的,结果表中行的数量和内容在游标打开的整个过程中不变。不敏感的游标不能用于数据更新和删除。 敏感的游标意味着在游标打开后,能够看到其他应用对基础表所作的更改,结果表中行的数量(其他应用插入或删除)在游标打开的整个过程中不变,但是行的内容可变 。敏感的游标能够用于数据更新和删除。
静态游标和动态游标的区别: 静态游标打开后,结果集的大小不变,结果集中行的数据顺序也不变。 动态游标打开后,结果集的大小可变,结果集中行的数据顺序也可变,即其他游标可以对结果集中进行插入,更新或删除操作。
各游标定义和取数据时各不同参数的区别总结 DECLARE CURSOR时使用的参数 FETCH时使用的参数 注释 对基础表更改的敏感性 INSENSITIVE FETCH缺省值是INSENSITIVE 无 SENSITIVE 无效组合 --- 有效组合 应用能看到自身采用positioned更新和删除所作的改变 FETCH缺省值是SENSITIVE 应用能看到: 1.自身采用positioned和searched更新和删除所作的改变 2.其他应用提交的更新和删除
样例:利用INSENSITIVE(不敏感) SCROLLABLE(可滚动) 游标实现多行数据查询样例
在第六个例子中,通过使用不敏感可滚动游标(INSENSITIVE SCROLL CURSOR)将样例表中的数据选出多行并显示于屏幕。 由于要用到DB2临时空间,需要做以下一些准备工作:
8.7.1 创建临时数据库 创建存放临时数据的临时数据库TEMP:
8.7.2 创建临时表空间 在临时数据库里创建表空间。由于创建全局临时表要求创建在至少8KB页大小的分段的表空间里,所以创建表空间时参数BUFFER POOL不能指定为BP0-BP49,参数SEGSIZE必须指定。 在主机DB2系统中,4KB页大小缓冲池分别命名为BP0-BP49; 8KB页大小缓冲池分别命名为BP8K0-BP8K9 ; 16KB页大小缓冲池分别命名为BP16K0-BP16K9 ; 32KB页大小缓冲池分别命名为BP32K,BP32K1-BP32K9 。
8.7.3 创建全局临时表 在临时数据库里创建全局临时表,提交时删除临时表内的行.
8.7.4 COBOL源程序 COBOL源程序如下:
8.7.5 预编译、编译、链接、执行COBOL源程序的JCL 预编译、编译、链接、执行COBOL源程序的JCL如下,系统参数通过JCL程序提供:
8.7.6 确认执行结果 确认查询结果:
8.8 利用敏感静态可滚动游标实现多行数据查询样例 在第七个例子中,通过敏感静态可滚动游标(SENSITIVE STATIC SCROLL CURSOR)将样例表中的数据选出多行并显示于屏幕。 8.8.1 COBOL源程序 COBOL源程序如下:
8.8.2 预编译、编译、链接、执行COBOL源程序的JCL 预编译、编译、链接、执行COBOL源程序的JCL如下,系统参数通过JCL程序提供:
8.8.3 确认执行结果 确认查询结果如下:
8.9 使用可更新游标更新表数据样例 在第八个例子中,通过可更新游标更新样例表中的一行数据并将成功或失败的消息显示于屏幕。 8.9.1 COBOL源程序 COBOL源程序如下:
8.9.2 预编译、编译、链接、执行COBOL源程序的JCL 预编译、编译、链接、执行COBOL源程序的JCL如下,系统参数通过JCL程序提供:
8.9.3 确认执行结果 确认数据被更新:
8.10 不用可更新游标的数据更新样例 在第九个例子中,通过UPDATE语句更新样例表中的一行数据并将成功或失败的消息显示于屏幕。 8.10.1 COBOL源程序 COBOL源程序如下:
8.9.2 预编译、编译、链接、执行COBOL源程序的JCL 预编译、编译、链接、执行COBOL源程序的JCL如下,系统参数通过JCL程序提供:
8.9.3 确认执行结果 确认数据被更新:
8.10 数据删除样例 在第十个例子中,通过DELETE语句删除样例表中的一行数据并将成功或失败的消息显示于屏幕。 8.10.1 COBOL源程序 COBOL源程序如下:
shi
8.10.2 预编译、编译、链接、执行COBOL源程序的JCL 预编译、编译、链接、执行COBOL源程序的JCL如下,系统参数通过JCL程序提供:
8.10.3 确认执行结果 确认数据被删除: