我为内务作业编写了一个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 @
答案 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',这将绕过错误的执行,并避免突然终止存储的过程。