1.靜態(tài)SQL與動(dòng)態(tài)SQL
Oracle編譯PL/SQL程序塊分為兩個(gè)種:一種是,SQL語(yǔ)句在程序編譯期間就已經(jīng)確定,大多數(shù)的編譯情況屬于這種類(lèi)型,如:靜態(tài)SQL;另外一種是SQL語(yǔ)句只有在運(yùn)行階段才能建立,例如當(dāng)查詢條件為用戶輸入時(shí),那么Oracle的SQL引擎就無(wú)法在編譯期對(duì)該程序語(yǔ)句進(jìn)行確定,只能在用戶輸入一定的查詢條件后才能提交給SQL引擎進(jìn)行處理。如:動(dòng)態(tài)SQL。
本文主要就動(dòng)態(tài)SQL的基礎(chǔ)做總結(jié)。
2.使用EXECUTE IMMEDIATE語(yǔ)句處理相關(guān)語(yǔ)句:
動(dòng)態(tài)SQL是一種”不確定”的SQL,那其執(zhí)行就有其相應(yīng)的特點(diǎn)。Oracle中提供了Execute immediate語(yǔ)句來(lái)執(zhí)行動(dòng)態(tài)SQL,語(yǔ)法如下:
Excute immediate 動(dòng)態(tài)SQL語(yǔ)句 using 綁定參數(shù)列表 returning into 輸出參數(shù)列表;
- USING 子句給動(dòng)態(tài)語(yǔ)句傳值
例如:
declare
l_str1 varchar2(20) := 'hello';
l_str2 varchar2(10) := 'world';
begin
execute immediate 'insert into t_str values (:1, :2, :3)'
using 50, l_str1 , l_str2 ;
commit; -----一定要顯示提交
end;
4.INTO子句從動(dòng)態(tài)語(yǔ)句檢索值
例如:
declare
v_cnt varchar2(20);
begin
execute immediate 'select count(1) from emp' into v_cnt ;
dbms_output.put_line(v_cnt );
end;
5.傳遞并檢索值.INTO子句用在USING子句前
例如:
declare
v_empno pls_integer := 20;
v_ename varchar2(20);
v_esex varchar2(20);
begin
execute immediate 'select ename, esex from emp where empno = :1'
into v_ename,v_esex
using v_empno ;
end;
6.輸出參數(shù)returning into 子句用在USING子句后
例如:
create or replace procedure update_data(stuid varchar2, age number)
as
strSQL varchar2(1000);
strID varchar2(50);
strName varchar2(50);
strSex varchar2(50);
begin
strSQL := 'update tb_student set age=:a where id=:b returning id, name, sex into :c, :d, :e';
execute immediate strSQL using age, stuid returning into strID, strName, strSex;
execute immediate 'commit'; -- 這樣也是可以的
dbms_output.put_line('ID:' || strID || ' ;Name:' || strName || ' ;Sex:' || strSex);
end;
在上面的代碼中,:a、:b、:c、:d和:e都是占位符,占位符必須以冒號(hào)開(kāi)始,名字無(wú)所謂。使用了占位符以后,就需要在execute immediate語(yǔ)句后面使用using將參數(shù)傳遞進(jìn)去,參數(shù)將與占位符一一對(duì)應(yīng)。但是有一點(diǎn)需要謹(jǐn)記,綁定參數(shù)不能是表名、列名、數(shù)據(jù)類(lèi)型等,綁定參數(shù)只能是值、變量或者表達(dá)式。用DDL語(yǔ)句動(dòng)態(tài)創(chuàng)建對(duì)象時(shí),應(yīng)該使用連接運(yùn)算符||,最好不要使用綁定參數(shù)。
另外上述代碼中還使用了一個(gè)returning into的關(guān)鍵語(yǔ)句,returning into語(yǔ)句的主要作用是:
delete操作:returning返回的是delete之前的結(jié)果
insert操作:returning返回的是insert之后的結(jié)果
update操作:returning語(yǔ)句是返回update之后的結(jié)果
7.通過(guò)游標(biāo)實(shí)現(xiàn)多行查詢的SELECT語(yǔ)句
例如:
declare
type ref_cur is ref cursor;
rc ref_cur;
seriesrow t_Md_Vehicle_Series%rowtype;
v_sql varchar2(500):='select * from t_Md_Vehicle_Series m where m.vehicle_make_id=:makeid';
v_sql2 varchar2(500);
type tb_model_type is table of t_md_vehicle_model%rowtype;
model_array tb_model_type;
begin
DBMS_OUTPUT.ENABLE(100000);
open rc for v_sql using 'CN001';
loop
FETCH rc INTO seriesrow;
EXIT WHEN rc%NOTFOUND;
dbms_output.put_line('name:'||seriesrow.vehicle_series_name||'--------------> id:'||seriesrow.vehicle_series_id);
v_sql2:='select * from t_md_vehicle_model m where m.vehicle_series_id=:seriesid and m.valid_flag=1';
execute immediate v_sql2 bulk collect into model_array using seriesrow.vehicle_series_id;
for i in model_array.first .. model_array.last loop
dbms_output.put_line('ID:' || model_array(i).vehicle_sub_model_id
|| '--------------> Name:' || model_array(i).vehicle_sub_model_name );
end loop;
end loop;
CLOSE rc;
end;
輸出結(jié)果:

上述語(yǔ)句中,用帶有子句bulk collect into的execute immediate語(yǔ)句。采用bulk collect into可以將查詢結(jié)果一次性地加載到集合中,可以在select into、fetch into、returning into語(yǔ)句中使用bulk collect into;但是需要特別注意的是,在使用bulk collect into時(shí),所有的into變量都必須是集合類(lèi)型。