--3.2 繫結變數:using → 只需要解析一次;
begin
execute immediate
'update emp set sal=sal*2 where empno=:p_empno' using &p_eno;
commit;
end;
注意:不能使用繫結變數替換實際的資料庫物件名(表,檢視,列等),只能替換字面量,
如果物件名是在執行時生成的,我們仍然需要對其用字串拼接,同時,sql只會匹配已經
在共享池中相同的物件名
在動態sql中使用繫結變數和不使用繫結變數的效能測試(在測試表中新增10000條記錄):
--建立測試表demo;
drop table demo;
create table demo(d_id number(6) primary key);
select * from demo;
--1.不使用繫結變數
declare
begin_time number(10);
end_time number(10);
begin
begin_time := dbms_utility.get_time;
execute immediate
'truncate table demo';
for i in 1..10000
loop
execute immediate
'insert into demo(d_id) values('||i||')';
end loop;
end_time :=dbms_utility.get_time;
dbms_output.put_line((end_time-begin_time)/100||'秒');
end;
--耗時12.88秒
--使用繫結變數
declare
begin_time number(10);
end_time number(10);
begin
begin_time := dbms_utility.get_time;
execute immediate
'truncate table demo';
for i in 1..10000
loop
execute immediate
'insert into demo(d_id) values(:x)' using i;
end loop;
end_time :=dbms_utility.get_time;
dbms_output.put_line((end_time-begin_time)/100||'秒');
end;
--耗時6.56秒
從上面的測試可以看出,使用繫結變數明顯比字串拼接的效率高得多。
用本地動態sql技術執行動態sql的方法
--1.無繫結變數的非sql查詢語句
begin
execute immediate
'create index emp_ind_1 on emp(sal,hiredate)';
end;
--注意:如果指向ddl語句時使用繫結變數是非法的
declare
v_sql_str varchar2(100);
begin
v_sql_str := 'update emp set sal=999 where empno=7788';
execute immediate v_sql_str;
end;
--2.帶固定數目繫結變數的非sql查詢語句
declare
v_sql_str varchar2(100);
begin
v_sql_str:='update emp set sal = :sal where empno = :eno';
execute immediate v_sql_str using 9999,7788;
end;
--帶returning子句;
declare
v_sql_str varchar2(100);
v_sal emp.sal%type;
v_ename emp.ename%type;
begin
v_sql_str :=
'update emp set sal=999 where empno=7788 returning ename,sal into :1,:2';
execute immediate v_sql_str returning into v_ename, v_sal;
dbms_output.put_line(v_ename||'→'||v_sal);
end;
--帶固定數目列和繫結變數的sql查詢語句;
--1.返回單行資料
declare
v_sql_str varchar2(100);
v_ename emp.ename%type;
v_sal emp.sal%type;
begin
v_sql_str :=
'select ename,sal from emp where empno = :eno';
execute immediate v_sql_str into v_ename,v_sal using 7788;
dbms_output.put_line(v_ename||'→'||v_sal);
end;
--輸出「scott→3000」;
--2.返回多行資料
declare
type emp_cur is ref cursor;
my_emp_cur emp_cur;
my_emp_rec emp%rowtype;
begin
open my_emp_cur for 'select * from emp where deptno=:x' using 30;
loop
fetch my_emp_cur into my_emp_rec;
exit when my_emp_cur%notfound;
dbms_output.put_line(my_emp_rec.ename||'→'||my_emp_rec.sal);
end loop;
end;
--返回多行資料且帶有using和bulk collect into子句
declare
type emp_table_type is table of emp%rowtype index by binary_integer;
emp_table emp_table_type;
begin
execute immediate
'select * from emp where deptno=:x' bulk collect into emp_table using 30;
for i in 1..emp_table.count
loop
dbms_output.put_line(emp_table(i).ename||'→'||emp_table(i).sal);
end loop;
end;
--執行動態查詢語句.--案例:輸入要排序的欄位名,實現動態排序。.
declare
my_field varchar2(100);
str_sql varchar2(1000);
type emp_cur_type is ref cursor;
cur emp_cur_type;
e_row emp%rowtype;
begin. my_field := '&enter_the_order_field';
str_sql := 'select * from emp order by ' || my_field;
open cur for str_sql;
loop fetch cur into e_row;
dbms_output.put_line(e_row.deptno || '->' || e_row.empno || '->' ||
e_row.ename || '->' || e_row.sal);
exit when cur%notfound;
end loop;
close cur;
end;
注意:雖然變數繫結減少了硬編譯次數,節省了cpu等資源,大多是情況下使用它可以顯著的提高系統效能和系統的併發訪問量,
但是仍然有一些情況下不適合使用變數繫結:
1、對於隔相當長一段時間才執行一次的sql語句,利用繫結變數的好處會被不能有效利用優化器而抵消;
2、資料倉儲的情況下;
3、在對建有索引的字段,且字段(集)的集非常大時,利用繫結變數可能會導致查詢計畫錯誤,因而導致查詢效率非常低。
繫結變數和游標共享
變數繫結是oltp系統中乙個非常值得關注的技術點。良好的變數繫結會使oltp系統資料庫中的sql執行速度飛快,記憶體效率極高 不繫結變數可能會使oltp資料庫不堪重負,資源被sql解析嚴重消耗,系統顯得滯重而緩慢。6.1 什麼是變數繫結,為什麼要做變數繫結 在介紹繫結變數以前,首先要介紹一下sql究...
Oracle游標使用方法( 游標裡使用變數繫結)
游標 cursor 也叫游標,在關聯式資料庫中經常使用,在pl sql程式中可以用cursor與select一起對錶或者檢視中的資料進行查詢並逐行讀取。oracle游標分為顯示游標和隱式游標。顯示游標 explicit cursor 在pl sql程式中定義的 用於查詢的游標稱作顯示游標。隱式游標 ...
oracle變數繫結
一 游標 游標可以理解為sql語句的乙個控制代碼,也叫sql語句的指標,游標指向一條sql語句,oracle會話要執行一條sql時,首先要開啟游標。二 sql解析的過程 硬解析步驟 1.對sql語句進行語法檢查,看是否有語法錯誤 2.通過資料字典,檢查sql語句中涉及的物件和列是否存在 3.檢查sq...