所以我尝试将此代码更改为动态SQL
SELECT LISTAGG(accounting_dept || '-'||REPLACE(full_desc,'''',''''''), '; ') WITHIN GROUP (ORDER BY accounting_dept) FROM table
EXCUTE
12121-President''S Office
我改为动态sql
EXECUTE IMMEDIATE
' SELECT LISTAGG(accounting_dept || ''-''||REPLACE(full_desc,'''''',''''''''), ''; '') WITHIN GROUP (ORDER BY accounting_dept) FROM table '
INTO v_task;
错误是ORA-00907:缺少右括号
问题是这部分REPLACE(full_desc,''''','''''''',
如何在没有引发错误的情况下更改为动态sql?
答案 0 :(得分:5)
如果将语句放入变量中,则可以在执行之前输出它:
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;
/
显示它尝试执行的语句,然后显示错误:
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
如果在SQL Developer中手动运行该生成的语句,您将获得ORA-00907:缺少右括号;不完全确定你是如何或为什么动态地得到这个错误 - 它应该首先抱怨分号,使用ORA-00911。
您可以看到generate语句与您开始使用的原始静态语句不匹配。你需要有更多的转义报价:
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.
但正如Tony Andrews所建议的那样,而是使用替代引用机制。
这不是你甚至需要动态SQL;这样做:
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;
/
答案 1 :(得分:4)
如果将整个select
转换为字符串,请使用如下所示的Q引号:
q'[SELECT LISTAGG(accounting_dept || '-'||REPLACE(full_desc,'''',''''''), '; ') WITHIN GROUP (ORDER BY accounting_dept) FROM table]'