如何捕捉执行立即执行(打开)的错误?

时间:2019-08-05 15:00:27

标签: oracle plsql cursor procedure

我有此过程:

PROCEDURE proc_with_cursor(  P_PARAM1_IN NUMBER, P_PARAM2_IN NUMBER, P_CURSOR_OUT OUT SYS_REFCURSOR)
    IS
    v_sql   VARCHAR2 (32767);
    v_script   VARCHAR2 (32767);
    v_bind_vars VARCHAR2 (32767);
BEGIN
     v_sql := 'BEGIN OPEN :1 FOR :2 ';
     v_bind_vars := P_PARAM1_IN||', '||P_PARAM2_IN;
     v_sql := v_sql||' USING '||v_bind_vars||'; ';
    --tried also following  but also couldn't catch the error!
    --v_sql := v_sql ||'EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE(''error: ''||SQLCODE||'' - ''||SQLERRM); END;';
    v_sql := v_sql||' END;';

    v_script := 'select sysdate from dual where 1= :bind_first and 2 = :bindsecond';

    EXECUTE IMMEDIATE v_sql using P_CURSOR_OUT, v_script;     

    EXCEPTION 
    WHEN OTHERS THEN 
        DBMS_OUTPUT.PUT_LINE('error: '||SQLCODE||' - '||SQLERRM); -- this part is not catching the error!!!!!   
END;

有时,脚本将引发类似以下的错误:

  

ORA-12847:由于并发DDL操作而导致重试解析

     

[错误]执行(1:1):ORA-12847:由于并发DDL操作而导致重试解析

我的问题是:如何捕获该错误?

2 个答案:

答案 0 :(得分:2)

您不能将对象名称(例如光标名称)和变量名称绑定到动态SQL中,只能绑定。我认为这可能会实现您的预​​期:

PROCEDURE proc_with_cursor(  p_param1_in NUMBER, p_param2_in NUMBER, p_cursor_out OUT SYS_REFCURSOR)
IS
    v_script   VARCHAR2 (32767);
BEGIN
    v_script := 'select sysdate from dual where 1= :bind_first and 2 = :bindsecond';

    OPEN p_cursor_out FOR v_script USING p_param1_in, p_param2_in;

EXCEPTION
    WHEN OTHERS THEN
        dbms_output.put_line('error: '||sqlcode||' - '||sqlerrm); 
END;

答案 1 :(得分:0)

我不明白你的问题。如果您有此程序

CREATE OR REPLACE PROCEDURE proc_with_cursor(  p_param1_in NUMBER, p_param2_in NUMBER, p_cursor_out OUT SYS_REFCURSOR)
IS
    v_script   VARCHAR2 (32767);
BEGIN
    v_script := 'select sysdate fromM dual where 1= :bind_first and 2 = :bindsecond';
    OPEN p_cursor_out FOR v_script USING p_param1_in, p_param2_in;
END;

然后您得到这个:

DECLARE
    cur SYS_REFCURSOR;
BEGIN
    proc_with_cursor(1, 2, cur);    
end;
/

Error at line 1
ORA-00923: FROM keyword not found where expected
ORA-06512: at "xxx.PROC_WITH_CURSOR", line 6
ORA-06512: at line 4

您还想得到什么?您的(不良)代码有效:

CREATE OR REPLACE PROCEDURE proc_with_cursor(  P_PARAM1_IN NUMBER, P_PARAM2_IN NUMBER, P_CURSOR_OUT OUT SYS_REFCURSOR) IS
    v_sql   VARCHAR2 (32767);
    v_script   VARCHAR2 (32767);
    v_bind_vars VARCHAR2 (32767);
BEGIN
    v_sql := 'BEGIN OPEN :1 FOR :2 ';
    v_bind_vars := P_PARAM1_IN||', '||P_PARAM2_IN;
    v_sql := v_sql||' USING '||v_bind_vars||'; ';
    v_sql := v_sql||' END;';

    v_script := 'select sysdate fromm dual where 1= :bind_first and 2 = :bindsecond';

    EXECUTE IMMEDIATE v_sql USING P_CURSOR_OUT, v_script;     

EXCEPTION 
    WHEN OTHERS THEN 
        DBMS_OUTPUT.PUT_LINE('error: '||SQLCODE||' - '||SQLERRM);   
END;


DECLARE
    cur SYS_REFCURSOR;
BEGIN
    proc_with_cursor(1,2, cur);
END;

在DBMS_OUTPUT上打印error: -923 - ORA-00923: FROM keyword not found where expected

如果您想获得例外,那就做

CREATE OR REPLACE PROCEDURE proc_with_cursor(  P_PARAM1_IN NUMBER, P_PARAM2_IN NUMBER, P_CURSOR_OUT OUT SYS_REFCURSOR) IS
    v_sql   VARCHAR2 (32767);
    v_script   VARCHAR2 (32767);
    v_bind_vars VARCHAR2 (32767);
BEGIN
    ...    
    EXECUTE IMMEDIATE v_sql USING P_CURSOR_OUT, v_script;     

EXCEPTION 
    WHEN OTHERS THEN 
        DBMS_OUTPUT.PUT_LINE('error: '||SQLCODE||' - '||SQLERRM);  
        RAISE;  
END;
相关问题