在使用DB2数据库中的游标时,您可能会有这些问题:如果对一个表设置了游标,可不可以同时对这个表进行update操作? 怎么样操作才不会影响游标的位置? 本文将为您讲解处理的方法,供您参考。
使用定位操作更改行
可更新游标支持通过游标更新行的数据修改语句。当定位在可更新游标中的某行上时,您可以执行更新或删除操作,这些操作针对用于在游标中建立当前行的基表行。
这些就称为定位更新。
定位更新在打开游标的同一个连接上执行。
这就允许数据修改共享与游标相同的事务空间,并且使游标保持的锁不会阻止更新。
有两种方法在游标中执行定位更新:
UPDATE 或 DELETE 语句中的 Transact-SQL WHERE CURRENT OF 子句。
数据库 API 定位更新函数或方法,如 ODBC SQLSetPos 函数。
使用 Transact-SQL 执行定位更新
Transact-SQL WHERE CURRENT OF 子句典型用于 Transact-SQL 存储过程、触发器以及脚本
(当需要根据游标中特定行进行修改时)。存储过程、触发器、或脚本将:
DECLARE 和 OPEN 游标。
用 FETCH 语句在游标中定位于一行。
用 WHERE CURRENT OF 子句执行 UPDATE 或 DELETE 语句。用 DECLARE 语句中的 cursor_name
作为 WHERE CURRENT OF 子句中的 cursor_name。
例程:
declare cursor_name cursor for #p#
select * from T2
for update
open cursor_name
fetch next from cursor_name
while @@Fetch_Status = 0
begin
update T2 set sname = 'lx_' + sname --right(sname,len(sname)-3)
where current of cursor_name
fetch next from cursor_name
end
close cursor_name
deallocate Cursor_Name
在DB2中也有类似的用法,由于DB2中的SQL语法和SQL SERVER有所不同,所以DB下的存储过程如下:
CREATE PROCEDURE KYJT.SP_TESTT ( )
SPECIFIC KYJT.SQL060421171925193
LANGUAGE SQL
NOT DETERMINISTIC
CALLED ON NULL INPUT
MODIFIES SQL DATA
INHERIT SPECIAL REGISTERS
BEGIN
DECLARE PNAME VARCHAR(50);
DECLARE PID INT;
DECLARE v_count int;
DECLARE SQLSTATE CHAR(5);
DECLARE at_end INT DEFAULT 0; #p#
DECLARE not_found CONDITION FOR SQLSTATE '02000';
DECLARE C1 CURSOR FOR SELECT ID,NAME FROM KYJT.TESTT FOR UPDATE ;
DECLARE CONTINUE HANDLER FOR not_found
SET at_end = 1;
OPEN C1;
INS_LOOP:
LOOP
FETCH C1 INTO PID,PNAME;
if at_end = 1 then
LEAVE INS_LOOP;
END IF;
UPDATE KYJT.TESTT A
SET NAME = (SELECT NAME FROM KYJT.TEST B WHERE B.ID=PID) WHERE CURRENT OF C1;
END LOOP;
CLOSE C1;
END