Как @Giga указал, что построение оператора sql в виде конкатенации строк является очень плохой идеей . Не только опасно подвергаться инъекции sql, но и безобразно и совершенно не нужно. Вы уже используете dbms_ sql для проверки запроса - кстати, хорошая идея - так почему бы не построить запрос с учетом этого. Так что с вашим запросом, используя dbms_ sql до конца:
-- Setup
create table "Mat Val"
( nume integer
, prenume integer
, nr_matricol integer
, valoare integer
, data_notare integer
);
declare
k_materie_name varchar2(8) := 'Mat Val';
k_sql_base varchar2(1000) :=
'insert into "v_materie" (nume,prenume,nr_matricol,valoare,data_notare) values(:1,:2,:3,:4,:5)';
l_sql_stmt varchar2(1000);
l_dbms_cursor_ref integer;
l_rows_processed integer;
v_nume integer := 1;
v_prenume integer := 2;
v_nr_matricol integer := 3;
v_valoare integer := 4;
v_data_notare integer := 5;
begin
l_sql_stmt := replace(k_sql_base,'v_materie',k_materie_name);
dbms_output.put_line('Setting up dbms_sql processing for statement:' || chr(10) || l_sql_stmt);
l_dbms_cursor_ref:= dbms_sql.open_cursor;
dbms_sql.parse(l_dbms_cursor_ref,l_sql_stmt,DBMS_SQL.native);
-- set up bind variables with local variables
dbms_sql.bind_variable(l_dbms_cursor_ref, ':1', v_nume);
dbms_sql.bind_variable(l_dbms_cursor_ref, ':2', v_prenume);
dbms_sql.bind_variable(l_dbms_cursor_ref, ':3', v_nr_matricol);
dbms_sql.bind_variable(l_dbms_cursor_ref, ':4', v_valoare);
dbms_sql.bind_variable(l_dbms_cursor_ref, ':5', v_data_notare);
-- execute dynamic sql
l_rows_processed := dbms_sql.execute(l_dbms_cursor_ref);
dbms_output.put_line('Rows inserted to "' || k_materie_name || '" ==> ' || to_char(l_rows_processed));
dbms_sql.close_cursor(l_dbms_cursor_ref);
end ;
Или просто dbms_ sql, чтобы подтвердить запрос, а затем вернуться к немедленному выполнению:
declare
k_materie_name varchar2(8) := 'Mat Val';
k_sql_base varchar2(1000) :=
'insert into "v_materie" (nume,prenume,nr_matricol,valoare,data_notare) values(:1,:2,:3,:4,:5)';
l_sql_stmt varchar2(1000);
l_dbms_cursor_ref integer;
l_rows_processed integer;
v_nume integer := 21;
v_prenume integer := 32;
v_nr_matricol integer := 43;
v_valoare integer := 54;
v_data_notare integer := 65;
begin
l_sql_stmt := replace(k_sql_base,'v_materie',k_materie_name);
dbms_output.put_line('Setting up executee immediate for statement:' || chr(10) || l_sql_stmt);
l_dbms_cursor_ref:= dbms_sql.open_cursor;
dbms_sql.parse(l_dbms_cursor_ref,l_sql_stmt,DBMS_SQL.native);
dbms_sql.close_cursor(l_dbms_cursor_ref);
execute immediate l_sql_stmt
using v_nume
, v_prenume
, v_nr_matricol
, v_valoare
, v_data_notare;
dbms_output.put_line('Rows inserted to "' || k_materie_name || '" ==> ' || to_char(sql%rowcount));
end ;
В любом случае Никогда не строить SQL с конкатенацией строк . Планируйте и используйте переменные связывания. Это безопаснее, поскольку исключает внедрение SQL, но также ваш код чище и на самом деле легче писать (мне всегда нужно сначала написать отдельное утверждение для его тестирования, затем преобразование в переменные связывания относительно просто). Наконец, если один и тот же оператор выполняется несколько раз с разницей только в значениях, он выполняется быстрее, так как избегает сложного анализа.