That's because the statement isn't using binds!
As soon as you start using string concatenation for values like this:
|| '(' || l_all_vals_indx || ')'';
You're generating a new SQL statement for each new value for L_ALL_VALS_INDX.
I'm unsure exactly what you're trying to do here, but it looks like a generic "accept a table name and some columns and insert the values" procedure. In which case you need to bind the these values in the outer EXECUTE IMMEIDATE along these lines:
begin
execute immediate q'!
declare
stmt clob;
begin
stmt := 'insert into ' || :tab || ' values ( ' || :v1 || ' )';
execute immediate stmt;
end;!'
using 'T', 1;
end;
/
That said, nesting EXECUTE IMMEDIATEs inside each other always makes things tricky and is
best avoided.
Unless there's an
absolutely critical reason for doing this dynamically, you're almost always better off writing static SQL statements for each table. Static SQL is more secure, easier to debug, and avoids generating many unique SQLs.
If you're trying to avoid listing all the columns out, PL/SQL record-based inserts are a better way to go:
declare
trec t%rowtype;
begin
trec := init_t ( ... );
insert into t values trec;
end;
/