Предполагая, что это упрощенный пример чего-то, что действительно должно быть динамичным, одна проблема заключается в том, что строковые значения не заключаются в кавычки. (Если бы у вас были значения даты, они также нуждались бы в специальной обработке.)
Например:
create table demo (numcol number, stringcol varchar2(20));
declare
l_num number := 123;
l_string varchar2(20) := 'Kittens';
l_sql long := 'insert into demo(numcol, stringcol) values ('||l_num||', '||l_string||')';
begin
dbms_output.put_line(l_sql);
execute immediate l_sql;
end;
/
Сгенерированный код:
insert into demo(numcol, stringcol) values (123, Kittens)
Сбой с:
ORA-00984: column not allowed here
Ошибка будет зависеть от содержимого строки. Например, если он содержит пробелы:
declare
l_num number := 123;
l_string varchar2(20) := 'Kittens are cute';
l_sql long := 'insert into demo(numcol, stringcol) values ('||l_num||', '||l_string||')';
begin
dbms_output.put_line(l_sql);
execute immediate l_sql;
end;
/
Сгенерированный код:
insert into demo(numcol, stringcol) values (123, Kittens are cute)
ORA-00917: missing comma
или запятые:
declare
l_num number := 123;
l_string varchar2(20) := 'Kittens, Puppies';
l_sql long := 'insert into demo(numcol, stringcol) values ('||l_num||', '||l_string||')';
begin
dbms_output.put_line(l_sql);
execute immediate l_sql;
end;
/
insert into demo(numcol, stringcol) values (123, Kittens, Puppies)
ORA-00913: too many values
Вам необходимо заключить в кавычки:
declare
l_num number := 123;
l_string varchar2(20) := 'Kittens, Puppies';
l_sql long := 'insert into demo(numcol, stringcol) values ('||l_num||', '''||l_string||''')';
begin
dbms_output.put_line(l_sql);
execute immediate l_sql;
end;
/
так что вы генерируете
insert into demo(numcol, stringcol) values (123, 'Kittens, Puppies')
(Если строка может содержать символы кавычек, это потребует дополнительной работы.)
Стоит всегда строить динамический SQL какпеременной и распечатывает или регистрирует ее при сбое, поскольку обычно достаточно ясно, в чем проблема, когда вы видите код.
Другой момент заключается в том, что объединение таких значений требует больших ресурсов, поскольку Oracle пытается кешироватьОператоры SQL для повторного использования, поэтому они будут анализироваться и оптимизироваться индивидуально и занимать место в кеше, но никогда не будут использоваться повторно. Если это будет часто выполняться с разными значениями, вам следует рассмотреть возможность использования переменных связывания через предложение using
в execute immediate
.