【问题标题】:Errror executing dynamic delete query with Prepare statement inside a DB2 Stored Procedure in IBM DB2 LUW在 IBM DB2 LUW 中的 DB2 存储过程中使用 Prepare 语句执行动态删除查询时出错
【发布时间】:2019-06-06 14:09:16
【问题描述】:

我正在尝试从具有大量记录的表中删除记录。

现在错误是

'Cursor 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 删除

【问题讨论】:

标签: stored-procedures db2 commit db2-luw


【解决方案1】:

许多错误。
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

【讨论】:

  • 你好马克,非常感谢你的解决方案。我对上述 SP 做了一些小修正。我添加了一个'END IF;'在“提交;”之后。该解决方案适用于最多 400M 行的所有表,但对于具有 +500M 行且错误“事务日志已满”的表失败。我相信这不应该是这种情况,因为我们已经在每次执行 COMMIT 之后10K。请问有什么建议吗?
  • @KKS 我真的忘记关闭IF 语句了,但是它必须在COMMIT 语句之前关闭,而不是在它之后。否则代码无法正确提交。它必须在每个DELETE 之后提交,但是如果您将END IF; 放在COMMIT 之后,则在所有删除后它只提交一次。检查更新的示例。
猜你喜欢
  • 2019-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-26
  • 2019-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多