我只编写了几天的DB2过程,但试图在给定的表上进行“批量删除”。我的预期逻辑是:
为了简化这个问题,假设我只想在WHILE循环完成后发出一个COMMIT(所有DELETE)(即一旦光标到达EOF)。所以给出下面的代码示例:
CREATE TABLE tableA (colA INTEGER, ...)
CREATE PROCEDURE "SCHEMA"."PURGE_PROC"
(IN batchSize INTEGER)
LANGUAGE SQL
SPECIFIC SQL140207163731500
BEGIN
DECLARE tempID INTEGER;
DECLARE eof_bool INTEGER DEFAULT 0;
DECLARE sqlString VARCHAR(1000);
DECLARE sqlStmt STATEMENT;
DECLARE myCurs CURSOR WITH HOLD FOR sqlStmt;
DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET eof_bool = 1;
SET sqlString = 'select colA from TableA';
PREPARE sqlStmt FROM sqlString;
OPEN myCurs;
FETCH myCurs INTO tempID;
WHILE (eof_bool = 0) DO
DELETE FROM TableA where colA = tempID;
FETCH myCurs INTO tempID;
END WHILE;
COMMIT;
CLOSE myCurs;
END
注意:在我的真实场景中:
但是,为了简化,我测试了上面的代码,我看到的是DELETE似乎是逐个提交的。我基于以下测试:
如果所有DELETE都立刻被提交,我希望看到记录计数(*)在~60秒结束时仅从0下降到0。这就是我在为Oracle或SQLServer编写的类似SP中看到的。
这是Win2003上的DB2 v9.5。
我缺少什么想法?
答案 0 :(得分:0)
您缺少不同数据库引擎之间的并发控制实现的差异。在Oracle数据库中,另一个会话将看到在其事务开始之前已提交的数据,也就是说,在第一个会话提交之前,它不会看到任何删除。
在DB2中,根据服务器配置参数(例如DB2_SKIPDELETED
)和/或第二个会话隔离级别(例如未提交的读取),它实际上可以看到(或不看到)受到正在进行的事务影响的数据。
如果您的业务逻辑需要不同的事务隔离,请与您的DBA联系。
答案 1 :(得分:0)
应该指出你正在删除“光标之外”
使用光标删除的正确方法是使用“定位删除”
DELETE FROM tableA WHERE CURRENT OF myCurs;
以上内容删除刚刚获取的行。