Ошибка выполнения динамического запроса на удаление с оператором Prepare внутри хранимой процедуры DB2 в IBM DB2 LUW - PullRequest
0 голосов
/ 06 июня 2019

Я пытаюсь удалить записи из таблиц с огромным объемом записей.

Теперь ошибка

'Курсор C1 определяет подготовленный оператор, который не является оператором SELECT илиЗНАЧЕНИЯ '

1-добавлено COMMIT, без использования COMMIT' Журналы транзакций 'становятся полными.2. Добавлен оператор WITH HOLD, чтобы курсор оставался активным.

Строки с '--NEW ADDED' показывают новый добавленный код для уже работающего удаления без COMMIT и WITH HOLD

CREATE PROCEDURE
TABLE1.MYPROC1 ( IN A VARCHAR(100),IN B INTEGER,IN C INTEGER)
LANGUAGE SQL
BEGIN
DECLARE SQLCODE int;
DECLARE V_CREATE_QUERY VARCHAR(1024);
DECLARE V_DELETE_STATEMENT STATEMENT;
DECLARE C1 CURSOR WITH HOLD FOR V_DELETE_STATEMENT;--NEW ADDED

SET V_CREATE_QUERY='DELETE FROM (SELECT * FROM '||a||' WHERE KEY         
=='||RTRIM(CHAR(B)||' ' FETCH FIRST ' || RTRIM (CHAR(C)||' ROWS ONLY ) AS 
PURGE_TABLE';

PREPARE V_DELETE_STATEMENT FROM V_CREATE_QUERY;
OPEN C1;  --NEW ADDED
WHILE(SQLCODE <>1000)
 DO
 EXECUTE V_DELETE_STATEMENT;
 COMMIT;  --NEW ADDED
END WHILE;
CLOSE C1  --NEW ADDED
end

Пожалуйста, дайте мне знать, как удалить, используя COMMIT и WITH HOLD

1 Ответ

0 голосов
/ 06 июня 2019

Количество ошибок.
Вам не нужен курсор для delete.
SQLCODE = 100 (а не 1000) возвращается, если строки не удалены. Вы должны проверить его сразу после соответствующего утверждения (delete в вашем случае), а не после другого утверждения (commit ?? в вашем примере).

Должно быть что-то вроде этого:

CREATE OR REPLACE PROCEDURE
TABLE1.MYPROC1 ( IN A VARCHAR(100),IN B INTEGER,IN C INTEGER)
LANGUAGE SQL
BEGIN
  DECLARE SQLCODE int;
  DECLARE V_CREATE_QUERY VARCHAR(1024);
  DECLARE V_DELETE_STATEMENT STATEMENT;

  SET V_CREATE_QUERY=
    'DELETE FROM (SELECT * FROM '||a
  ||' WHERE KEY='||RTRIM(CHAR(B)
  ||' FETCH FIRST ' || RTRIM (CHAR(C)||' ROWS ONLY ) AS PURGE_TABLE';

  PREPARE V_DELETE_STATEMENT FROM V_CREATE_QUERY;
  DEL_LOOP: LOOP
    EXECUTE V_DELETE_STATEMENT;
    IF (SQLCODE = 100) THEN LEAVE DEL_LOOP; END IF;
    COMMIT;
  END LOOP DEL_LOOP;
  COMMIT;
end
...