【问题标题】:Stored procedure not deleting the records from db2存储过程不从 db2 中删除记录
【发布时间】:2015-03-19 16:52:49
【问题描述】:
CREATE OR REPLACE PROCEDURE  WRK.PURGE_ACH_BATCH_TAB_1()
LANGUAGE SQL

BEGIN
    -- Declare cursor
    DECLARE v_CNT_BLOCK INTEGER;
    DECLARE Ac_no BIGINT;
    DECLARE SQLSTATE CHAR(5) DEFAULT '00000'; 
    DECLARE mycur cursor for 
        SELECT t.TNX_Ac_no
        FROM WRK.BATCH_TAB1 c
            INNER JOIN WRK.BATCH_TAB t
                ON c.BATCH_ID = t.BATCH_ID
                    AND c.PROCESS_ID = t.process_ID
        WHERE c.BATCH_START_TS < (CURRENT DATE -7 days); 

    set v_CNT_BLOCK = 0;
    open mycur;

    FETCH FROM mycur INTO Ac_no;
    WHILE(SQLSTATE = '00000') DO
        DELETE FROM WRK.BATCH_TAB1 b WHERE b.TNX_Ac_no = Ac_no;
        SET v_CNT_BLOCK=v_CNT_BLOCK+1;
        if v_CNT_BLOCK >= 5 then
            set v_CNT_BLOCK = 0;
            commit;
        end if;

        FETCH FROM mycur INTO Ac_no;  

    END WHILE; 

    CLOSE mycur; 

    commit; 

END
@ 

我在 db2 表中有 19 条记录来满足分配给游标的条件,执行此命令后我得到了成功命令,但没有一个值从 db 中删除。请帮助我在哪里遗漏了什么。

【问题讨论】:

  • 为什么这个标签是Oracle?这似乎与 Oracle 无关。
  • 注意游标,声明时没有WITH HOLD子句,第一次提交后会关闭。

标签: sql stored-procedures db2


【解决方案1】:

看来您正试图从光标正在读取的同一个表中删除。根据您运行的隔离级别,您可能会遇到锁定错误。

在您的示例代码中,似乎没有任何理由首先使用光标。您应该删除该集合。

DELETE 
FROM WRK.BATCH_TAB1 c
WHERE EXISTS (SELECT 1 FROM WRK.BATCH_TAB t
               WHERE c.BATCH_ID = t.BATCH_ID
                 AND c.PROCESS_ID = t.process_ID
             )
AND c.BATCH_START_TS < (CURRENT DATE -7 days); 

鉴于对 cme​​ts 中相关性的修正:

DELETE 
FROM WRK.BATCH_TAB1 c
WHERE EXISTS (SELECT 1 FROM WRK.BATCH_TAB t
               WHERE c.BATCH_ID = t.BATCH_ID
                 AND c.PROCESS_ID = t.process_ID
                 AND t.BATCH_START_TS < (CURRENT DATE -7 days)
             );

或者,如果由于示例中不明显的原因必须使用光标,则应该查看 DELETE 语句的“定位形式”:

DELETE FROM WRK.BATCH_TAB1 WHERE CURRENT OF CURSOR mycur;

删除光标刚刚返回的记录。当然,使用INNER JOIN 时,它不适用于您原来的光标。但是,如果您使用我上面答案中的WHERE EXISTS 语法,则可以选择删除。

【讨论】:

  • 嗨查尔斯..为什么要使用游标..我的表有很多事务..所以我想删除一些记录并且必须立即提交...并想继续下一个级别记录。
  • 你的意思是说..我们不能使用带光标的内连接。
  • 从 WRK.BATCH_TAB1 c 中删除(从 WRK.BATCH_TAB 中选择 1,其中 c.BATCH_ID = t.BATCH_ID 和 c.PROCESS_ID = t.process_ID)和 t.BATCH_START_TS
  • 应该只是能够将其移动到 EXISTS 子句中。编辑我的答案以显示这一点。至于内部连接,不,我的意思是您不能使用具有定位删除连接的游标。
  • charles.,你能帮忙动态处理这个查询吗?DELETE FROM (SELECT * FROM WRK.BAH_T c WHERE EXISTS (SELECT 1 FROM WRK.BAH_C t WHERE c.BAH_ID = t.BAH_ID AND c. PID = t.pID AND VARCHAR_FORMAT (c.BAH_START_TS,''YYYY-MM-DD''))
【解决方案2】:

在足够新的 DB2 版本上,您应该能够执行以下操作:

BEGIN
 DECLARE SQLSTATE CHAR(5) DEFAULT '00000';
 loop1: WHILE SQLSTATE = '00000' DO
  DELETE FROM (
   SELECT FROM WRK.BATCH_TAB1 c
   WHERE EXISTS (SELECT 1 FROM WRK.BATCH_TAB t
               WHERE c.BATCH_ID = t.BATCH_ID
                 AND c.PROCESS_ID = t.process_ID
                 AND t.BATCH_START_TS < (CURRENT DATE -7 days)
   ) FETCH FIRST 5 ROWS ONLY
  );
  IF SQLSTATE = '02000' THEN -- not found
   LEAVE loop1;
  END IF;
  COMMIT;
 END WHILE;
END@

【讨论】:

  • 您好 Musta... 我需要动态传递天数或日期和记录数...在上述情况下... DELETE FROM (SELECT * FROM WRK.BATCH_TAB1 c WHERE EXISTS (SELECT 1 FROM WRK.BATCH_TAB t WHERE c.BATCH_ID = t.BATCH_ID AND c.PROCESS_ID = t.process_ID AND VARCHAR_FORMAT(c.BAdate,''YYYY-MM-DD'')
  • 我正在尝试从 store proc 输入参数中传递日期 pDATE 和 N.. 你能帮我编辑一下吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-14
  • 1970-01-01
相关资源
最近更新 更多