循环过程来截断表SQL Developer

时间:2015-12-02 17:53:24

标签: oracle stored-procedures plsql oracle-sqldeveloper

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

我收到了以下代码的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;

2 个答案:

答案 0 :(得分:1)

您不会以这种方式捕获异常,您必须使用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秒。

答案 1 :(得分:0)

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;