2011-03-05 3 views
0

이론적으로 데이터베이스에서 데이터 용으로 큰 볼륨을 삭제할 수있는 정리 작업을 위해 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

나는 비슷한 요구 사항을 가지고있었습니다. 내 요구를 충족시키기 위해 작성한 저장 프로 시저를 아래에서 찾으십시오.

SET SERVEROUTPUT [email protected] 

drop procedure [email protected] 
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; 

[email protected] 

당신은 추가 할 수는 잘못된 실행을 우회하여 저장된 프로 시저의 갑작스러운 종료를 방지하여야한다 저장 프로 시저에 'SQLSTATE XXXX CONTINUE 핸들러 선언'.