Oracle:動態sql
阿新 • 來源:網路 • 發佈:2022-12-30
一、概述
二、執行ddl、dcl語句
三、處理dml語句
1、給動態語句傳值(USING 子句)
2、從動態語句檢索值(INTO子句)
3、動態呼叫儲存過程
4、處理包含returing子句的DML語句
5、在retuing into中使用bulk collect into
四、處理多行查詢
1、使用動態遊標(遊標變數)處理多行查詢類動態sql語句
2、在execute immediate中使用bulk collect into
3、在forall語句中使用bulk collect into語句
一、概述
在一般的sql操作中,sql語句基本上都是固定的,如: SELECT t.empno,t.ename FROM scott.emp t WHERE t.deptno = 20; 但有的時候,從應用的需要或程式的編寫出發,都可能需要用到動態SQl,如: 當 from 後的表 不確定時,或者where 後的條件不確定時,都需要用到動態SQL。使用execute immediate語句可以處理包括ddl(create、alter和drop)、DCL(grant、revoke)、DML(insert、update、delete)以及單行select語句。
execute immediate語句:
execute immediate dynamic_string
[into {define_variable[,define_variable]…|record}]
[using [in|out|in out] bind_argument[,[in|out|in out]bind_argument]…]
[{returning|return} into bind_argument[, bind_argument]…]
define_variable用於指定存放單行查詢結果的變數;
using in bind_argument用於指定存放傳遞給動態sql值的變數,即在dynamic中存在佔位符時使用;
using out bind_argument用於指定存放動態sql返回值的變數。
二、執行ddl、dcl語句
不能使用into和using子句begin
execute immediate 'create table ma_org(org_codevarchar2(20),org_name varchar2(254))';
execute immediate 'drop table ma_org';
end;
語句
begin
execute immediate 'grant insert on ma_org to scott'
end;
三、處理dml語句
1、給動態語句傳值(USING 子句)
如果dml語句包含佔位符,那麼在execute immediate語句之後必須要帶有using子句;declare
orgcode varchar2(10);
orgname varchar2(254);
begin
orgcode := 1200;
execute immediate 'select org_name fromma_org
where org_code = :X'
into orgname
using orgcode;
dbms_output.put_line(orgname);
end;
2、從動態語句檢索值(INTO子句)

3、動態呼叫儲存過程
declare
l_routin varchar2(100) := 'gen2161.get_rowcnt';
l_tblnam varchar2(20) := 'emp';
l_cnt number;
l_status varchar2(200);
begin
execute immediate 'begin ' || l_routin || '(:2, :3, :4); end;'
using in l_tblnam, out l_cnt, in out l_status;
if l_status != 'OK' then
dbms_output.put_line('error');
end if;
end;
4、處理包含returing子句的DML語句
如果dml語句帶有returning子句,那麼在execute immediate語句之後必須帶有returning into子句,並且此時只能處理作用的單行上的dml語句,如果dml語句作用在多行上,則必須使用bulk子句。declare
orgcode varchar2(10);
orgname varchar2(254);
rname varchar2(254);
begin
orgcode := '1200';
orgname := '天津市分行';
execute immediate 'update ma_org set org_name=:X
where org_code = :Y returning org_name into :rname'
using orgname, orgcode
returning into rname;
dbms_output.put_line(orgname);
end;
5、在retuing into中使用bulk collect into

四、處理多行查詢
oracle通過使用bulk collect into子句處理動態sql中的多行查詢可以加快處理速度,從而提高應用程式的效能。當使用bulk子句時,集合型別可以是plsql所支援的索引表、巢狀表和varray,但集合元素必須使用sql資料型別。在oracle9i以後,有三種語句支援bulk子句,execute immediate,fetch和forall。1、使用動態遊標(遊標變數)處理多行查詢類動態sql語句
DECLARE
TYPE ref_cur IS REF CURSOR;
rc ref_cur;
emprow emp%ROWTYPE;
v_sql VARCHAR2(100):= 'select * from emp where deptno = :x'; --動態執行的SQL語句
BEGIN
OPEN rc FOR v_sql USING 30; --開啟遊標,繫結執行的SQL語句,並傳遞引數
LOOP
FETCH rc INTO emprow;
EXIT WHEN rc%NOTFOUND;
dbms_output.put_line('name:'||emprow.ename||' sal:'||emprow.sal);
END LOOP;
CLOSE rc;
END;
2、在execute immediate中使用bulk collect into
示例1:declare
type org_table_type is table of ma_org%rowtype;
org_table org_table_type;
v_orgcode varchar2(20);
begin
v_orgcode := '%00%';
execute immediate 'select * from ma_org where org_code like:v_orgcode' bulk collect into org_table
using v_orgcode;
for i in 1..org_table.count
loop
dbms_output.put_line(org_table(i).org_code||','||org_table(i).org_name);
end loop;
end;
示例2:
declare
type org_table_type is table of z_dangan%rowtype index by binary_integer;
org_table org_table_type;
v_orgcode varchar2(200);
begin
v_orgcode := '%王%';
execute immediate 'select * from z_dangan where xingming like:v_orgcode' bulk collect into org_table
using v_orgcode;
commit;
for i in 1..org_table.count loop
dbms_output.put_line(org_table(i).xingming);
end loop;
end;
3、在forall語句中使用bulk collect into語句
declare
type type_org_code is table of ma_org.org_code%type;
type type_org_name is table of ma_org.org_name%type;
v_orgcode type_org_code;
v_orgname type_org_name;
begin
v_orgcode := type_org_code('1100','1200');
forall i in 1..v_orgcode.count
execute immediate 'update ma_org set org_name = org_code||org_namewhere org_code = :p1 returning org_name into :p2'
using v_orgcode(i)
returning bulk collect into v_orgname;
for i in v_orgname.first..v_orgname.last
loop
dbms_output.put_line(v_orgname(i));
end loop;
end;
declare
type type_org_code is table of z_dangan.danganid%type;
type type_org_name is table of z_dangan.xingming%type;
v_orgcode type_org_code;
v_orgname type_org_name;
names varchar(20);
begin
v_orgcode := type_org_code('000480090000000002', '000480020000000005');
names := '測試';
forall i in 1 .. v_orgcode.count execute immediate
'update z_dangan set xingming =:p1 where danganid =:p2 returning xingming into :p3'
using names, v_orgcode(i) returning bulk collect into
v_orgname
;
for i in v_orgname.first .. v_orgname.last loop
dbms_output.put_line(v_orgname(i));
end loop;
end;
