DB2数据库游标使用总结

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 16:41   1811   0

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

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP