DB2存储过程 - 控制大记录删除

时间:2011-03-05 18:45:05

标签: database stored-procedures db2

我为内务作业编写了一个DB2存储过程,理论上可以从数据库中删除大量数据。

要求是通过一次提交一定数量的记录来控制删除。

首先,我想对我的存储过程提出一些反馈,看看我是否有任何改进。

其次,我有一个关于SQL错误的问题。如果在循环迭代期间发生错误,存储过程是否立即退出?理想情况下,我想继续循环尝试删除尽可能多的记录。我不确定我的脚本是否以这种方式工作。


CREATE PROCEDURE leave_loop(IN commit_unit INTEGER, OUT counter INTEGER)
LANGUAGE SQL
BEGIN
  DECLARE v_prod_id INTEGER;
  DECLARE v_delete_counter INTEGER DEFAULT 0;
  DECLARE v_total INTEGER DEFAULT 0;
  DECLARE not_found CHAR(1) DEFAULT 'N';

  DECLARE c1 CURSOR WITH HOLD FOR
    SELECT prod_id
    FROM product
    WHERE status_deleted = 1
    ORDER BY prod_id;
  DECLARE CONTINUE HANDLER FOR NOT FOUND
    SET not_found = 'Y'; 

  SET counter = 0;

  OPEN c1;
  delete_loop:
  LOOP
    -- Fetch the record
    FETCH c1 INTO v_prod_id;

    -- If not row found then leave the loop
    IF not_found = 'Y' THEN
      -- If we have not reached the commit unit the commit the outstanding records
      IF v_delete_counter > 0 THEN
        COMMIT;
      END IF;
      LEAVE delete_loop;
    END IF;

    -- Perform the deletion
    DELETE FROM product WHERE prod_id = v_prod_id;

    SET v_delete_counter = v_delete_counter + 1;

    -- Check if the commit unit has been reached
    IF MOD(v_delete_counter, commit_unit) = 0 THEN
      COMMIT;
      SET v_delete_counter = 0;
      SET v_total = v_total + 1;
    END IF; 

  END LOOP delete_loop;
  CLOSE c1;

  SET total = v_total;
END @

1 个答案:

答案 0 :(得分:1)

我过去也有类似的要求。请在下面找到我为满足我的需求而编写的存储过程。

SET SERVEROUTPUT ON@ 

drop procedure DELETE_WITH_COMMIT_COUNT@
CREATE PROCEDURE DELETE_WITH_COMMIT_COUNT(IN v_TABLE_NAME VARCHAR(24), IN v_COMMIT_COUNT INTEGER, IN v_WHERE_CONDITION VARCHAR(1024))
    NOT DETERMINISTIC
    LANGUAGE SQL
BEGIN
-- DECLARE Statements
DECLARE SQLCODE INTEGER;
DECLARE v_COUNTER INTEGER DEFAULT 0;
DECLARE v_DELETE_QUERY VARCHAR(1024);
DECLARE v_DELETE_STATEMENT STATEMENT;

SET v_DELETE_QUERY = 'DELETE FROM (SELECT 1 FROM ' || v_TABLE_NAME || ' WHERE ' || v_WHERE_CONDITION
    || ' FETCH FIRST ' || RTRIM(CHAR(v_COMMIT_COUNT)) || ' ROWS ONLY) AS DELETE_TABLE';

PREPARE v_DELETE_STATEMENT FROM v_DELETE_QUERY;

DEL_LOOP:
    LOOP
        SET v_COUNTER=v_COUNTER + 1;

        EXECUTE v_DELETE_STATEMENT;

        IF SQLCODE = 100 THEN
            LEAVE DEL_LOOP; 
        END IF;
        COMMIT;

    END LOOP;

COMMIT;

END@

您可以在存储过程中添加'DECLARE CONTINUE HANDLER FOR SQLSTATE XXXX',这将绕过错误的执行,并避免突然终止存储的过程。