Firstly, why the second insert inside a PL/SQL block works and almost the same insert executed dynamically using execute immediate
statement doesn't? Simply because of name resolution. When second insert, that insert
statement which you've described as this one works great
is being executed iid
, dir
and in_fname
resolved to locally declared variables. And in case of the dynamically executed insert
statement those iid
, dir
resolved to column names of the table you are trying to insert data into, and it's simply not allowed to put column names of a table you are trying to insert into in the value
clause of an insert
statement. Use bind variables.
Secondly, about returning into
clause. You need two of them. One as part of a dynamically formed insert statement
(dynamic returning into
clause) and one for execute immediate
statement(static returning into
clause), in order to get returning by the insert statement values out. Or, one dynamic returning into
clause and one OUT
bind variable(in this case).
To that end, your anonymous pl/sql block might look like this:
declare
tablename varchar2(200) :='imagesroom';
temp varchar2(50) :='room_id';
iid number :=1;
dir varchar2(200) :='imgdirroom';
in_fname varchar2(100) :='img1.jpg';
obj ORDIMAGE;
ctx RAW(64) := NULL; -- really unnecessary, NULL by default.
l_instr varchar2(4000);
begin
l_instr := 'INSERT INTO ' || tablename || '('||temp||',extension,icon)
VALUES(:1,'''',ORDImage(''FILE'',upper(:2), :3))
RETURNING icon INTO :4';
execute immediate l_instr
using iid, dir, in_fname returning into obj;
end;
/