DB2数据库游标使用总结 工作中因需要使用DB2,所以逼迫自己学习db2游标的使用,上网看了很多材料,加上自己的一些总结,把最近的学习心得总结以下,希望对工作中使用DB2数据库的同学能有所帮助!
一、 DB2游标概述 游标的概念网上已经解释的很清楚了,我的理解,使用select语句都会产生一个结果集,这些结果集放在一个缓存空间,游标相当于一个指针变量,一行一行的读取结果集。 大概意思如下图所示:
 二、使用游标的语法 1. 声明一个游标: declare myCur cursor for select id from employee; 2. 打开游标: open myCur; --执行游标中的SQL语句 3. 读取游标: fetch myCur into v_id; --读取结果集中的一行数据 4. 关闭游标: close myCur; --释放结果集的空间
游标使用注意事项:
a. 游标必须再一个begin..end模块中声明和使用
b. 在游标的begin..end模块中,声明变量、游标以及条件处理要有序进行;普通变量声明在先,其次到游标的声明,最后才能声明condition handler
c. 结果集读取完毕后,会返回一个NOT FOUND的告警,通过抓取这个SQLCODE,可以控制循环的退出。
三、 游标使用案例 案例1: 使用游标,读取一行数据
/*
存储过程: SP_EMPLOYEE_SALARY
目的: 输入一个ID,返回该员工的salary,读一行数据
*/
CREATE OR REPLACE PROCEDURE SP_EMPLOYEE_SALARY(
IN V_EMPNO VARCHAR(6),
OUT V_SALARY DECIMAL(9,2)
)
BEGIN
DECLARE SQLCODE INTEGER DEFAULT 0;
DECLARE V_SQLCODE INTEGER;
BEGIN
DECLARE V_SAL DECIMAL(9,2);
DECLARE myCUR CURSOR FOR SELECT SALARY FROM EMPLOYEE WHERE EMPNO=V_EMPNO; /*声明游标*/
DECLARE CONTINUE HANDLER FOR NOT FOUND /*定义抓取异常NOT FOUND*/
BEGIN
SET V_SQLCODE = SQLCODE;
END;
OPEN myCUR; /*打开游标*/
FETCH myCUR INTO V_SAL; /*读取游标*/
SET V_SALARY = V_SAL;
CLOSE myCUR; /*关闭游标*/
END;
END
存储过程的编译和运行情况如下:
编译的方式有两种:
1. 通过客户端IBM Data Studio编译:

运行情况截图,在Linux命令模式下运行: [db2inst2@virtualone procedure]$ db2 "call SP_EMPLOYEE_SALARY('000130',?)"

2. 通过命令方式编译:
第一步: 将末尾的end加上一个@

第二步,在命令模式下: [db2inst2@virtualone procedure]$ db2 -td@ -f SP_EMPLOYEE_SALARY.sql,编译之后,运行方式与上面的一致,调用命令即可: db2 "call SP_EMPLOYEE_SALARY('000130',?)"

案例2: 采用循环读取游标
实现游标:使用循环方式把employee表的EMPNO,FIRSTNME字段数据插入ID_NAME表
1. 创建表
CREATE TABLE ID_NAME(
ID CHAR(6),
NAME VARCHAR(12)
)
2. 创建存储过程
CREATE OR REPLACE PROCEDURE SP_ID_NAME(
OUT REMSG VARCHAR(10)
)
BEGIN
DECLARE SQLCODE INTEGER DEFAULT 0;
DECLARE V_SQLCODE INTEGER;
DECLARE CONTINUE HANDLER FOR SQLWARNING
BEGIN
SET REMSG = 'WARNING';
END;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
SET REMSG = 'ABORTED';
END;
SET REMSG='SUCCESS';
BEGIN
DECLARE V_ID CHAR(6);
DECLARE V_NAME VARCHAR(12);
DECLARE myCUR CURSOR FOR SELECT EMPNO,FIRSTNME FROM EMPLOYEE; /*声明游标*/
DECLARE CONTINUE HANDLER FOR NOT FOUND /*定义抓取异常NOT FOUND*/
BEGIN
SET V_SQLCODE = SQLCODE;
END;
OPEN myCUR; /*打开游标*/
FETCH_LOOP: LOOP FETCH myCUR INTO V_ID,V_NAME; /*采用循环方式读取所有游标数据*/
/*当数据读取完时,就会抓取到not found 异常,SQLCODE就为100,赋值给V_SQLCODE,才可退出循环*/
IF (V_SQLCODE = 100) THEN
LEAVE FETCH_LOOP;
ELSE
INSERT INTO ID_NAME (ID,NAME) VALUES(V_ID,V_NAME);
END IF;
END LOOP FETCH_LOOP;
SET REMSG = 'CURSOR SUCCESS';
CLOSE myCUR; /*关闭游标*/
END;
END
代码的编译和运行方式与上面案例一样。
案例3: 使用动态SQL语句与游标相结合
/*实现游标:使用动态SQL与游标相结合实现把employee表的数据插入ID_NAME表*/
CREATE OR REPLACE PROCEDURE SP_STMT_ID_NAME(
OUT REMSG VARCHAR(50)
)
BEGIN
DECLARE SQLCODE INTEGER DEFAULT 0;
DECLARE V_SQLCODE INTEGER;
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
SET REMSG = 'ABORTED';
END;
SET REMSG='SUCCESS';
BEGIN
DECLARE V_ID CHAR(6);
DECLARE V_NAME VARCHAR(12);
DECLARE V_SELECT_SQL VARCHAR(100);
DECLARE V_INSERT_SQL VARCHAR(100);
DECLARE V_STMT STATEMENT;
DECLARE myCUR CURSOR FOR V_STMT; /*声明游标*/
DECLARE CONTINUE HANDLER FOR NOT FOUND /*定义抓取异常NOT FOUND*/
BEGIN
SET V_SQLCODE = SQLCODE;
END;
SET V_SELECT_SQL = 'SELECT EMPNO,FIRSTNME FROM EMPLOYEE';
PREPARE V_STMT FROM V_SELECT_SQL;
OPEN myCUR; /*打开游标*/
FETCH_LOOP: LOOP FETCH myCUR INTO V_ID,V_NAME; /*读取游标,采用循环方式读取所有游标数据*/
IF (V_SQLCODE = 100) THEN
LEAVE FETCH_LOOP;
ELSE
SET V_INSERT_SQL = 'INSERT INTO ID_NAME (ID,NAME) VALUES(' || V_ID|| ',''' || V_NAME || ''')';
PREPARE s from V_INSERT_SQL;
EXECUTE s;
END IF;
END LOOP FETCH_LOOP;
SET REMSG = 'CURSOR_SUCCESS';
CLOSE myCUR; /*关闭游标*/
END;
END
总结,以上的代码时基于db2的sample数据库上运行的,大家有兴趣可以去ibm官网上下载db2的免费版,在虚拟机上装个Linux,再装db2,就可以搭建好一个实验环境。
DB2游标的学习,给大家分享两个连接,这两篇文章也写得很用心,大家也可以综合参考以下:
https://www.iteye.com/blog/zhuyuehua-882826
https://www.cnblogs.com/Mr-kevin/archive/2016/07/04/5641182.html |