正如@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 注入,而且你的代码更干净,实际上更容易编写(我总是需要先编写一个独立的语句来测试它,然后转换为绑定变量相对简单)。最后,如果相同的语句多次运行,只是值不同,它会更快,因为它避免了硬解析。