【问题标题】:Looping Procedure to Truncate a table SQL Developer截断表的循环过程 SQL Developer
【发布时间】:2016-03-07 02:27:23
【问题描述】:

我正在尝试创建一个数据库过程来截断表,但如果该截断失败,请稍等片刻并重新运行截断。我无法锁定表或复制表然后删除旧表,所以这种更困难的方法是我唯一的选择。

我的以下代码收到 PLS-00382 错误,并为这个问题感到困惑:

CREATE OR REPLACE PROCEDURE TRUNCATE_ROUTING_CACHE AS
runcount   NUMBER := 0;
status      varchar2(10);


BEGIN

EXECUTE IMMEDIATE 'truncate table routing_cache';


IF VALUE_ERROR THEN
status := 'FAIL';

    WHILE status = 'FAIL' AND runcount < 3
        LOOP
        sys.dbms_lock.sleep(120);
        EXECUTE IMMEDIATE 'truncate table routing_cache';
          IF VALUE_ERROR THEN
             runcount := runcount + 1;

          ELSIF status = 'FAIL' THEN
             status := 'SUCCESS';

          END IF;

        END LOOP;

ELSIF runcount = 0 THEN
    status := 'SUCCESS';
    runcount := runcount + 1;
END IF;

END;

【问题讨论】:

    标签: oracle stored-procedures plsql oracle-sqldeveloper


    【解决方案1】:
    In my opinion we should check for locks first. If lock is there then wait event should be invoked. I have pasted a snippet below which will help you to go in right direction. Let me know if this helps.
    
    CREATE OR REPLACE PROCEDURE TRUNCATE_ROUTING_CACHE
    AS
      runcount NUMBER := 0;
      status   VARCHAR2(10);
      lv_cnt PLS_INTEGER;
    BEGIN
      --Checking first if any lock there on the object
      SELECT COUNT(1)
      INTO lv_cnt
      FROM V$LOCKED_OBJECT lc,
        ALL_OBJECTS obj
      WHERE lc.object_id  = obj.object_id
      AND obj.OBJECT_TYPE = 'TABLE'
      AND obj.OBJECT_NAME = 'ROUTING_CACHE';
      -- If lock present let it wait for 120 secs
      WHILE lv_cnt <> 0
      LOOP
        sys.dbms_lock.sleep(120);
        -- Again check foer the lock objects for any locks to continue loop
        SELECT COUNT(1)
        INTO lv_cnt
        FROM V$LOCKED_OBJECT lc,
          ALL_OBJECTS obj
        WHERE lc.object_id  = obj.object_id
        AND obj.OBJECT_TYPE = 'TABLE'
        AND obj.OBJECT_NAME = 'ROUTING_CACHE';
      END LOOP;
      -- Once lock clears up the Truncate command will be fired
      EXECUTE IMMEDIATE 'TRUNCATE TABLE ROUTING_CACHE';
    END;
    

    【讨论】:

      【解决方案2】:

      您不会以这种方式捕获异常,您必须使用 EXCEPTION WHEN 构造。我建议阅读Oracle's documentation on exception handling。我也很惊讶您正在寻找VALUE_ERROR,这仅涵盖在转换期间或放入变量时截断数字/日期。它不包括表格。

      这里的所有要求都是关于;这听起来确实不像您的数据模型是正确的;也许像global temporary table 这样的东西会更合适?

      但是,如果您确实需要这样做,那么我将其简化如下:

      begin
         loop
            begin
               execute immediate truncate table routing_cache';
               exit;
            exception when others then
               dbms_lock.sleep(120);
            end;
         end loop;
      end;
      

      这无限循环。如果在截断期间没有引发异常,则退出循环,否则休眠 120 秒。

      【讨论】:

      • 太棒了,我稍微改动了一下,只运行了 3 次。我计划添加额外的代码来报告它运行的次数等。
      猜你喜欢
      • 1970-01-01
      • 2015-10-16
      • 2022-01-23
      • 1970-01-01
      • 1970-01-01
      • 2021-12-01
      • 2010-10-12
      • 2013-06-05
      相关资源
      最近更新 更多