在Oracle中,如何在用于循环的表不存在时捕获异常

时间:2015-02-16 16:28:50

标签: oracle

我有这段代码:

BEGIN
    FOR
        U1 IN (SELECT * FROM SOME_USER.SOME_TABLE)
    LOOP
        BEGIN
            -- do something;
        END;
    END LOOP;
END;

我的问题是有时SOME_USER.SOMETABLE不存在,但我希望运行脚本的其余部分。我知道在运行代码之前(在IF ... THEN块中)检查表是否存在是行不通的,因为在编译时会评估SELECT * FROM SOME_USER.SOME_TABLE

另一个途径是使用SELECT运行EXECUTE IMMEDIATE。这样它将在运行时进行评估,我将能够捕获异常。很遗憾,我找不到使用EXECUTE IMMEDIATE循环U1 IN的方法。我该如何实现这个目标?

我使用的是Oracle 11g,SQL脚本是从Windows上的批处理脚本运行的。

4 个答案:

答案 0 :(得分:4)

您可以使用the 'OPEN FOR' syntax

DECLARE
    CUR SYS_REFCURSOR;
    <variables or record type> -- declare as appropriate
BEGIN
    OPEN CUR FOR 'SELECT * FROM SOME_USER.SOME_TABLE';
    LOOP
        FETCH CUR INTO <variables or record type>;
        EXIT WHEN CUR%NOTFOUND;
        -- do something with variables or record
    END LOOP;
    CLOSE CUR;
END;
/

您需要将每一行提取到变量或记录类型中,您不能使用%ROWTYPE,因为该表仍然不存在;如果适合您的数据量,您可以更改为批量提取。

如果你运行它仍然会得到ORA-00942,但如果这是在存储的程序中,你将无法在运行时获得它,现在你可以添加一个IF块来检查表格存在于OPEN之前。

拥有一个数据模型,其中对象在运行时可能存在或不存在,但看起来很可疑......

答案 1 :(得分:0)

您可以使用解决方法 - 创建嵌套表类型并将SELECT结果存储在其中。使用该类型循环遍历值。

所以,

SELECT data_obj(COL1, COL2) bulk collect into data_tbl_typ from data_table;

这部分可以进入动态sql。 (记得使用绑定变量)

然后在您的过程中循环遍历此嵌套表类型。

答案 2 :(得分:0)

使用DBMS_SQL包运行查询。

按照此Oracle文档中的示例进行操作:

http://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_sql.htm#sthref6147

答案 3 :(得分:-1)

pl / sql有异常条款。其他几乎所有东西都有。您可以在函数中处理异常,或者打印消息并将其传递回main。将你的功能分解成更小的功能,让每个功能都能抓住它自己的例外。

BEGIN
    FOR
        U1 IN (SELECT * FROM SOME_USER.SOME_TABLE)
    LOOP
        BEGIN
            -- do something;
        END;
    END LOOP;
EXCEPTION  
    WHEN OTHERS THEN
        DBMS_OUTPUT.PUT_LINE ('Oh well.  The table isn't there.');
        --RAISE;


END;