CREATE OR REPLACE PROCEDURE WRK.PURGE_ACH_BATCH_TAB_1()
LANGUAGE SQL
BEGIN
-- Declare cursor
DECLARE v_CNT_BLOCK INTEGER;
DECLARE Ac_no BIGINT;
DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
DECLARE mycur cursor for
SELECT t.TNX_Ac_no
FROM WRK.BATCH_TAB1 c
INNER JOIN WRK.BATCH_TAB t
ON c.BATCH_ID = t.BATCH_ID
AND c.PROCESS_ID = t.process_ID
WHERE c.BATCH_START_TS < (CURRENT DATE -7 days);
set v_CNT_BLOCK = 0;
open mycur;
FETCH FROM mycur INTO Ac_no;
WHILE(SQLSTATE = '00000') DO
DELETE FROM WRK.BATCH_TAB1 b WHERE b.TNX_Ac_no = Ac_no;
SET v_CNT_BLOCK=v_CNT_BLOCK+1;
if v_CNT_BLOCK >= 5 then
set v_CNT_BLOCK = 0;
commit;
end if;
FETCH FROM mycur INTO Ac_no;
END WHILE;
CLOSE mycur;
commit;
END
@
我在db2表中有19条记录,以满足分配给游标的条件,执行此操作后获取成功命令,但没有从db中删除任何值。请帮助我在哪里错过了什么。
答案 0 :(得分:1)
您似乎正在尝试从光标正在读取的同一个表中删除。根据您运行的隔离级别,可能会出现锁定错误。
在您的示例代码中,似乎没有任何理由首先使用游标。你应该删除该集。
DELETE
FROM WRK.BATCH_TAB1 c
WHERE EXISTS (SELECT 1 FROM WRK.BATCH_TAB t
WHERE c.BATCH_ID = t.BATCH_ID
AND c.PROCESS_ID = t.process_ID
)
AND c.BATCH_START_TS < (CURRENT DATE -7 days);
鉴于评论中相关性的修正:
DELETE
FROM WRK.BATCH_TAB1 c
WHERE EXISTS (SELECT 1 FROM WRK.BATCH_TAB t
WHERE c.BATCH_ID = t.BATCH_ID
AND c.PROCESS_ID = t.process_ID
AND t.BATCH_START_TS < (CURRENT DATE -7 days)
);
或者,如果您必须使用游标,原因在于您的示例中不明显的原因,那么您应该查看DELETE
语句的“定位形式”:
DELETE FROM WRK.BATCH_TAB1 WHERE CURRENT OF CURSOR mycur;
删除光标刚刚返回的记录。当然,使用INNER JOIN
对原始光标不起作用。但是,如果您使用上面我的答案中的WHERE EXISTS
语法,则定位删除将是一个选项。
答案 1 :(得分:1)
在最新的DB2版本上,您应该可以执行以下操作:
BEGIN
DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
loop1: WHILE SQLSTATE = '00000' DO
DELETE FROM (
SELECT FROM WRK.BATCH_TAB1 c
WHERE EXISTS (SELECT 1 FROM WRK.BATCH_TAB t
WHERE c.BATCH_ID = t.BATCH_ID
AND c.PROCESS_ID = t.process_ID
AND t.BATCH_START_TS < (CURRENT DATE -7 days)
) FETCH FIRST 5 ROWS ONLY
);
IF SQLSTATE = '02000' THEN -- not found
LEAVE loop1;
END IF;
COMMIT;
END WHILE;
END@