動態sql 和靜態sql 下篇
1、批量繫結讓oracle 在對一組值進行sql操作時繫結乙個變數,這一組資料可以是任何的plsql的聚合型別(聯合陣列,內嵌表,可變陣列),
集合元素必須是sql的資料型別,比如char date mumber。有三個句法支援動態批量繫結,execute immediate , fetch , forall;
execute immediate: 你可以用bulk collect into子句和execute immediate宣告去儲存 乙個查詢集合的每一列到乙個分散的集合中去。
你可以用returning bulk collect into子句和execute immediate去儲存insert ,update或者delete的結果集到乙個集合中。
fetch: 你可以用bulk collect into和fetch子句去儲存游標的每一列值到乙個集合中。
forall: 你可以用execute immediate宣告把returning bulk collect into放在乙個forall裡面.你可以去儲存insert ,update或者delete的結果集到乙個集合中。
2、動態繫結的例子:
動態sql中的bulk collect into 子句:
declare
type empcurtyp is ref cursor;
type numlist is table of number;
type namelist is table of varchar2(25);
emp_cv
empcurtyp;
empids
numlist;
empnames namelist;
sals
numlist;
begin
open emp_cv for ' select employee_id,last_name from employees';
fetch emp_cv bulk collect into empids,enames;
--批量存入內嵌表empids和enames。
close emp_cv;
--關閉游標
execute immediate ' select salary from employees' bulk cololect into sals;
--批量存入sals表。
end;
動態sql中的returning bulk collect into 和 using子句:
declare
type namelist is table of varchar2(15);
enames
namelist;
bonus_amt number:=50;
sql_stmt varchar2(200);
begin
sql_stmt:='update employees set salary =salary :1 returning last_name into :2';
execude
immediate sql_stmt
using bonus_amt returning bulk collect into enames; --sql_stmt中用了returning。。。。
end;
動態sql中用forall 和 using子句:
declare
type numberlist is table of number;
type namelist is table of varchar2(15);
empids numlist;
enames namelist;
begin
empids:=numlist(101,102,103,104,105);
forall i in 1..5
execute immediate
'update employees set salary=salaruy *1.04 where employee_id=:1 returning last_name into :2'
--注意這裡沒有分號結束,這個例子與上面的例子是不同的,這是一句整體的話。
using empids(i) returning bulk collect into enames;
end;
3、提高帶有繫結變數的動態sql的效能
當你在plsql語句中用到 insert ,update,delete,select語句時,plsql把變數自動的轉變成繫結的變數,這樣就能使語句執行的更加迅速,
但是在動態sql中,你需要自己去繫結變數,以達到更好地效能。
下面的例子中,oracle為每個單獨的emp_id開啟了乙個單獨的cursor,這樣帶來的資源競爭和效能低下是可想而知的:
create procedure fire_employee (emp_id
number) as
begin
execute immediate 'delete from employee where employee_id=' || to_char(emp_id);
end;
當然我們可以用下面的繫結變數的方法,為不同的emp_id重用乙個cursor:
create procedure fire_employee(emp_id) as
begin
execute immediate 'delete from employee where employee_id= :id' using emp_id;
--這句話就表示繫結了變數。
end;
看下面乙個傳遞物件名作為引數的例子:
create procudure drop_table(table_name in varchar2) as
begin
execute immediate 'drop table' || table_name;
end;
如果你要呼叫乙個不知道名字的過程(當執行時才知道名字):
create procedure run_proc(proc_name in varchar2, table_name in varchar2) as
begin
execute immediate 'call "
' || proc_name| | ' "( :proc_name) ' using table_name;
end;
下面來呼叫上面的過程:
create table employees_temp as select last_name from employees;
begin
run_proc('drop_table' , 'employees_temp');
--傳入兩個實參,乙個是過程引數drop_table過程,另乙個是表employees_temp。
end;
4、重複佔位符的使用:
在動態sql中,佔位符和變數的繫結是由位置決定的,而不是由名字決定的,有乙個例子很好的說明一下:
sql_stmt :='insert into payroll values(:x,:x,:y,:x)';
在這裡x是沒有實際意義的,它只是佔據了乙個位置,在using子句中你可以繫結四個不同的值:
execute immediate sql_semt using a,a,b,a;
如果乙個動態的宣告代表了乙個plsql塊,那這個規則就不一樣了:每乙個單獨的佔位符在using子句中對應乙個單獨的字元。如果相同的佔位符出現多次,在using子句中和繫結的變數一致的參照的名字相對應:
create procedure calc_stats(w number , x number , z number ) is
begin
dbms_output.put_line(w x y z);
end; /
declare a
number:=4; b
number:=7;
plsql_block varchar2(100); --宣告乙個plsql塊的字串。
begin
plsql_block:='begin calc_stats(:x , :x, :y, :x, ) ;
end ;';
--這是在乙個plsql塊中的佔位符,注意與上面的區分好。
execute immediate plsql_block using a,b;
--a代表先出現的x,b代表後出現的y。
end;
5、在動態sql中用cursor的屬性(%found, %isopen, %notfount, %rowcount):
declare
type cursor_ref is ref cursor;
c1 cursor_ref;
type emp_tab is table of employees%rowtype;
rec_tab emp_tab;
rows_fetched
number;
begin
open c1 for 'select * from employees';
fetch c1 bulk collect into rec_tab;
rows_fetched:=c1%rowcount;
dbms_output.put_line('number of employees fetched:' || to_char(rows_fetched));
end;
**:
Oracle動態SQL和靜態SQL比較
oracle動態sql和靜態sql比較 1 靜態sqlsql與動態sql oracle編譯pl sql程式塊分為兩個種 其一為前期聯編 early binding 即sql語句在程式編譯期間就已經確定,大多數的編譯情況屬於這種型別 另外一種是後期聯編 late binding 即sql語句只有在執行...
靜態SQL與動態SQL的比較
靜態sql與動態sql相比具備很多優點,最主要的表現在兩個方面 1 靜態sql指定具體的物件,可以避免動態sql中隱含的錯誤 2 靜態sql的分析和執行速度比動態sql要快 1 尋找消除動態sql的機會 一般而言,想採用動態sql實現的語句中都有不確定的因素,如果所有資訊都確定,沒有理由採用動態sq...
靜態SQL與動態SQL的比較
靜態sql與動態sql相比具備很多優點,最主要的表現在兩個方面 1 靜態sql指定具體的物件,可以避免動態sql中隱含的錯誤 2 靜態sql的分析和執行速度比動態sql要快 1 尋找消除動態sql的機會 一般而言,想採用動態sql實現的語句中都有不確定的因素,如果所有資訊都確定,沒有理由採用動態sq...