我有此过程:
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操作而导致重试解析
我的问题是:如何捕获该错误?
答案 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;