Oracle游標繫結變數使用

2021-09-01 04:39:39 字數 4422 閱讀 5974

--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...