Reputation: 208
I have this 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;
Sometimes, the script will throw an error like:
ORA-12847: retry parsing due to concurrent DDL operation
[Error] Execution (1: 1): ORA-12847: retry parsing due to concurrent DDL operation
My question is: how to catch that error?
Upvotes: 0
Views: 3801
Reputation: 59456
I don't understand your problem. If you have this procedure
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;
Then you get this:
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
What else would you like to get? Your (poor) code is working:
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;
Prints error: -923 - ORA-00923: FROM keyword not found where expected
on the DBMS_OUTPUT.
If you like to get the exception then do
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;
Upvotes: 0
Reputation: 132580
You cannot bind object names (e.g. cursor names) and variable names into dynamic SQL, only values. I think this may do what you intend:
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;
Upvotes: 2