我正在尝试创建一个截断表的数据库过程,但是如果截断失败则暂时等待并重新运行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;
答案 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;