Хранимая процедура DB2 - контролируемое удаление больших записей - PullRequest
0 голосов
/ 05 марта 2011

Я написал хранимую процедуру 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 Ответ

1 голос
/ 09 декабря 2013

У меня были подобные требования в прошлом. Пожалуйста, найдите ниже хранимую процедуру, которую я написал для удовлетворения моих потребностей.

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' к вашей хранимой процедуре, что позволит избежать ошибочных выполнений и позволит избежать внезапного завершения хранимого процесса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...