跟屌丝一起学习 DB2 第五课 存储过程(二)
REPEAT语句
ftch_loop2:
REPEAT
FETCH c1 INTO v_firstname, v_midinit, v_lastname;
UNTIL SQLCODE <> 0 AND REPEAT ftch_loop2;
WHILE语句
WHILE at_end = 0 DO
FETCH c1 INTO v_firstname, v_midinit, v_lastname;
IF SQLCODE = 100 THEN
SET at_end = 1;
END IF;
END WHILE;
LEAVE和ITERATE语句
LEAVE和ITERATE语句来控制循环
LEAVE语句用来跳出循环
ITERATE语句用来回到for或者while循环的开始重新执行
示例
FETCH_LOOP1: LOOP
FETCH c1 INTO v_dept, v_deptname, v_admdept;
IF at_end = 1 THEN
LEAVE FETCH_LOOP1;
ELSEIF v_dept = ‘D01’ THEN
ITERATE FETCH_LOOP1;
END IF;
INSERT INTO department(deptno, deptname, admdept)
VALUES(‘NEW’, v_deptname, v_admdept);
END LOOP FETCH_LOOP1;
GOTO语句
GOTO语句用于直接跳转到指定标签处。例如:
IF v_DEPT = ‘D11’
GOTO bye;
……
bye:
RETURN语句
RETURN语句用于向调用返回。
IF v_DEPT = ‘D11’
RETURN 1;
八 游标和结果集
游标的声明
下面是游标声明的几个例子:
DECLARE c1 CURSOR FOR select * from staff;
(DECLARE关键字,cl游标名称, CURSOR是必须有的,;指通过c1的游标来操作staff里所有的数据)最常用的最普通的。
2.DECLARE c1 CURSOR WITH HOLD FOR select * form staff;
3.DECLARE c1 CURSOR WITH RETURN TO CALLER FOR select * form staff;
4.DECLARE c1 CURSOR WITH RETURN TO CLIENT FOR select * form staff;
游标的相关操作
打开游标
OPEN <游标名>
提取游标
FETCH <游标名> INTO <变量列表>
关闭游标
CLOSE <游标名>
游标的遍历
DECLARE at_end INT DEFAULT 0; (声明了at_end的变量,默认值是0)
DECLARE PIID INTEGER DEFAULT 0;
DECLARE PINT INTEGER DEFAULT 0;
DECLARE not_found CONDITION FOR SQLSTATE '02000';
DECLARE c1 CURSOR FOR SELECT IID FROM YH; (声明了一个游标,把IID的指标拿出来)
DECLARE CONTINUE HANDLER FOR not_found SET at_end = 1;
OPEN c1; (进行循环)
SET PCOUNT = 0;
ins_loop: LOOP
FETCH c1 INTO PIID;
IF at_end <> 0 THEN
LEAVE ins_loop; ( LEAVE跳出循环)
END IF;
SET PCOUNT = PCOUNT + 1; (表示提取了多少条记录)
END LOOP;
删除游标对应的数据行
DECLARE cursor1 CURSOR FOR
SELECT DEPTNO, DEPTNAME, LOCATION
FROM DB2ADMIN.ORG FOR UPDATE;(声明一个cursor1的游标,从一个表时提出部门名称,...,位置)
OPEN cursor1;(打开游标)
FETCH FROM cursor1 INTO v_DEPTNO, V_DEPTNAME, v_LOCATION;
DELETE FROM DB2ADMIN.ORG WHERE CURRENT OF cursor1;(删除DB2ADMIN.ORG的记录; CURRENT OF cursor1这是的游标是指向某一个位置;删除游标指向的当前行。)
CLOSE cursor1;(关闭游标,也可做一个循环,删除所有的内容)
更新游标对应的数据行
九 异常处理器
DECLARE cursor1 CURSOR FOR
SELECT DEPTNO, DEPTNAME, LOCATION
FROM DB2ADMIN.ORG
FOR UPDATE;
OPEN cursor1;
FETCH FROM cursor1 INTO v_DEPTNO, v_DEPTNAME, v_LOCATION;
UPDATE DB2ADMIN.ORG SET DEPTNAME = ‘NEW NAME’WHERE CURRENT OF cursor1;
CLOSE cursor1;
使用游标返回多个结果集
九 异常处理器
异常处理器的声明
DECLARE handler-type HANDLER FOR condition handler-action;
(语法结构)(异常处理器是需要预先声明的)
异常处理器的类型(handler-type)
异常处理器的类型有如下几种:
CONTINUE(继续)
在异常处理器操作完成之后,会继续执行产生这个异常语句之后的下一条语句。
EXIT(记录完后就退出,不再继续执行)
在异常处理器操作完成之后,存储过程会终止,并将控制返回给调用者。
UNDO(撤销所做的记录,退出整个程序)
在异常处理器操作执行之前,DB2会回滚存储过程中执行的SQL操作。在异常处理器操作完成之后,存储过程会终止,并将控制返回给调用者。
异常处理器和SQLSTATE
异常处理器可以处理基于特定SQLSTATE值的定制异常,或者处理预定义异常的类。预定义的3种异常如下所示:
NOT FOUND
标识导致SQLCODE值为+100或者SQLSATE值为02000的异常。这个异常通常在SELECT没有返回行的时候出现。
SQLEXCEPTION
标识导致SQLCODE值为负的异常。
SQLWARNING
标识导致警告异常或者导致+100以外的SQLCODE正值的异常。
注:如果产生了NOT FOUND 或者SQLWARNING异常,并且没有为这个异常定义异常处理器,那么就会忽略这个异常,并且将控制流转向下一个语句。如果产生了SQLEXCEPTION异常,并且没有为这个异常定义异常处理器,那么存储过程就会失败,并且会将控制流返回调用者
异常处理器示例
如下示例声明了两个异常处理器。 EXIT处理器会在出现SQLEXCEPTION 或者SQLWARNING异常的时候被调用。EXIT处理器会在终止SQL程序之前,将名为stmt的变量设为“ABORTED”,并且将控制流返回给调用者。UNDO处理器会将控制流返回给调用者之前,回滚存储过程体中已经完成的SQL操作。
DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING
SET stmt = 'ABORTED';
DECLARE UNDO HANDLER FOR NOT FOUND;
异常处理器定制
如果预定义异常集不能满足需求,就可以为特定的SQLSTATE值声明定制异常,然后再为这个定制异常声明处理器。语法如下:
DECLARE unique-name CONDITION FOR SQLSATE 'sqlstate'
更为复杂的异常处理器示例(1 of 2)
-- Generic Handler
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND
BEGIN NOT ATOMIC
-- Capture SQLCODE & SQLSTATE
SELECT SQLCODE, SQLSTATE
INTO hSqlcode, hSqlstate
FROM SYSIBM.SYSDUMMY1;
-- Use the poGenStatus variable to tell the procedure -- what type of error occurred
CASE hSqlstate
WHEN '02000' THEN
SET poGenStatus=5000;
WHEN '42724' THEN
SET poGenStatus=3;
ELSE IF (hSqlCode < 0) THEN
SET poGenStatus=hSqlCode;
END IF;
END
上面的异常处理器会在出现SQLEXCEPTION, SQLWARNING, NOT FOUND异常的时候触发。异常处理器会取出当前的SQLCODE, SQLSTATE,然后根据它们的值来设置输出参数(poGenStatus)的值。
十 编写和调试存储过程
创建存储过程
将存储过程部署到本地或远程DB2数据库
修改并重新部署存储过程
对存储过程进行测试和Debug
使用Command Editor创建存储过程(1 of 3)