Reputation: 1621
so I try to change this code to dynamic SQL
SELECT LISTAGG(accounting_dept || '-'||REPLACE(full_desc,'''',''''''), '; ') WITHIN GROUP (ORDER BY accounting_dept) FROM table
excute
12121-President''S Office
I changed to dynamic sql
EXECUTE IMMEDIATE
' SELECT LISTAGG(accounting_dept || ''-''||REPLACE(full_desc,'''''',''''''''), ''; '') WITHIN GROUP (ORDER BY accounting_dept) FROM table '
INTO v_task;
the error is ORA-00907: missing right parenthesis
The problem is this part REPLACE(full_desc,'''''',''''''''),
how can I change to dynamic sql without the cauing error?
Upvotes: 0
Views: 1069
Reputation: 191235
If you put your statement into a variable you can output it before it's executed:
set serveroutput on
declare
v_stmt varchar2(2000);
v_task varchar2(2000);
begin
v_stmt := 'SELECT LISTAGG(accounting_dept || ''-''||REPLACE(full_desc,'''''',''''''''), ''; '') WITHIN GROUP (ORDER BY accounting_dept) FROM some_table';
dbms_output.put_line(v_stmt );
execute immediate v_stmt into v_task;
end;
/
which displays the statement it tries to execute, and then the error that gets:
SELECT LISTAGG(accounting_dept || '-'||REPLACE(full_desc,''',''''), '; ') WITHIN GROUP (ORDER BY accounting_dept) FROM some_table
Error report -
ORA-00911: invalid character
ORA-06512: at line 7
If you run that generated statement manually in SQL Developer you'll get ORA-00907: missing right parenthesis; not entirely sure how or why you're getting that error dynamically too - it should be complaining about the semicolon first, with the ORA-00911.
You can see that the generates statement does not match the original static statement you started with. You need to have even more escaped quotes:
declare
v_stmt varchar2(2000);
v_task varchar2(2000);
begin
v_stmt := 'SELECT LISTAGG(accounting_dept || ''-''||REPLACE(full_desc,'''''''',''''''''''''), ''; '') WITHIN GROUP (ORDER BY accounting_dept) FROM some_table';
dbms_output.put_line(v_stmt );
execute immediate v_stmt into v_task;
end;
/
SELECT LISTAGG(accounting_dept || '-'||REPLACE(full_desc,'''',''''''), '; ') WITHIN GROUP (ORDER BY accounting_dept) FROM some_table
PL/SQL procedure successfully completed.
But do as Tony Andrews suggests, and use the alternative quoting mechanism instead.
Not that you even need dynamic SQL here; this does the same:
declare
v_task varchar2(2000);
begin
SELECT LISTAGG(accounting_dept || '-'||REPLACE(full_desc,'''',''''''), '; ')
WITHIN GROUP (ORDER BY accounting_dept)
INTO v_task
FROM tableinto v_task;
end;
/
Upvotes: 5
Reputation: 132570
If turning the whole select
into a string, use Q quote like this:
q'[SELECT LISTAGG(accounting_dept || '-'||REPLACE(full_desc,'''',''''''), '; ') WITHIN GROUP (ORDER BY accounting_dept) FROM table]'
Upvotes: 4