DB2使用光标
问题描述:
DB2 V9的z/OSDB2使用光标
CREATE PROCEDURE SERDB.I21MMSNOUPD()
RESULT SETS 1
LANGUAGE SQL
FENCED
COLLID SER
WLM ENVIRONMENT DDSNSPENV
RUN OPTIONS 'NOTEST(NONE,*,*,*)'
P1: BEGIN
--Declare variables
DECLARE CONSUMER INTEGER;
DECLARE NEW_MMS_NO INTEGER;
DECLARE END_TABLE INT DEFAULT 0;
DECLARE C1 CURSOR FOR
SELECT I20_CONSUMER_ID,
NEW_MMS_NO
FROM SERDB.I20_TEMP
-- WHERE I20_CONSUMER_ID = 164921;
ORDER BY I20_CONSUMER_ID;
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET END_TABLE = 1;
OPEN C1;
FETCH C1 INTO CONSUMER,
NEW_MMS_NO;
WHILE END_TABLE = 0 DO
UPDATE SERDB.I20_CONSUMER_T
SET I20_MMS_NO = NEW_MMS_NO
WHERE I20_CONSUMER_ID = CONSUMER;
END WHILE;
CLOSE C1;
END P1
上述的存储过程存储过程建立与COND代码0,但未能执行即使当特定consumer_id。有没有人看到错误?
个别的sql语句完全按照它们应该运行的。
我已经遵循了IBM的SQL过程中游标的示例。
谢谢
答
我同意100%,@ X-Zero的,这似乎是一个巨大的工作定义游标和什么,而不是,当你可以做一个简单的基于集的操作(可能具有更好的性能的量)。下面是如何通过一个单一的操作做了两个例子:
普通UPDATE
:
UPDATE SESSION.I20_CONSUMER_T A
SET I20_MMS_NO = (
SELECT NEW_MMS_NO
FROM SESSION.I20_TEMP B
WHERE A.I20_CONSUMER_ID = B.CONSUMER
)
WHERE EXISTS (
SELECT 1
FROM SESSION.I20_TEMP C
WHERE A.I20_CONSUMER_ID = C.CONSUMER
)
新MERGE
热度:
MERGE INTO SESSION.I20_CONSUMER_T AS T
USING SESSION.I20_TEMP AS M
ON T.I20_CONSUMER_ID = M.CONSUMER
WHEN MATCHED THEN
UPDATE SET T.I20_MMS_NO = M.NEW_MMS_NO
ELSE IGNORE
这些都是对DB2测试的Linux/Unix/Windows v9.7,但应该在任何版本的DB2比9.1更新的版本上工作(DB2 for iSeries是通配符,我从来不记得那个平台做什么或不支持:)
)
+0
我的iSeries不支持'MERGE',但第一个应该可以正常工作(这正是我所想的)。 –
答
FETCH命令必须位于WHILE内部,以便每次调用时都会获取一行。
你知道这可能(可能)做得更好_overout光标,对不对?也就是说,假设更新行的大小不是太大(对于事务),这可以在单个“UPDATE”语句中完成。除非结果集是分页的(比如向用户显示时),或者更新/删除/需要“分批”(如果锁定的行数是太大了)。 –