Oracle中執(zhí)行動(dòng)態(tài)SQL
一、概述
在一般的sql操作中,sql語(yǔ)句基本上都是固定的,如: SELECT t.empno,t.ename FROM scott.emp t WHERE t.deptno = 20;
但有的時(shí)候,從應(yīng)用的需要或程序的編寫出發(fā),都可能需要用到動(dòng)態(tài)SQl,如:
當(dāng) from 后的表 不確定時(shí),或者where 后的條件不確定時(shí),都需要用到動(dòng)態(tài)SQL。
使用execute immediate語(yǔ)句可以處理包括ddl(create、alter和drop)、DCL(grant、revoke)、DML(insert、update、delete)以及單行select語(yǔ)句。
execute immediate語(yǔ)句:
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用于指定存放單行查詢結(jié)果的變量;
- using in bind_argument用于指定存放傳遞給動(dòng)態(tài)sql值的變量,即在dynamic中存在占位符時(shí)使用;
- using out bind_argument用于指定存放動(dòng)態(tài)sql返回值的變量。
二、執(zhí)行ddl、dcl語(yǔ)句
不能使用into和using子句。
begin execute immediate 'create table ma_org(org_codevarchar2(20),org_name varchar2(254))'; execute immediate 'drop table ma_org'; end;
語(yǔ)句
begin execute immediate 'grant insert on ma_org to scott' end;
三、處理dml語(yǔ)句
1、給動(dòng)態(tài)語(yǔ)句傳值(USING 子句)
如果dml語(yǔ)句包含占位符,那么在execute immediate語(yǔ)句之后必須要帶有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、從動(dòng)態(tài)語(yǔ)句檢索值(INTO子句)
3、動(dòng)態(tài)調(diào)用存儲(chǔ)過(guò)程
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語(yǔ)句
如果dml語(yǔ)句帶有returning子句,那么在execute immediate語(yǔ)句之后必須帶有returning into子句,并且此時(shí)只能處理作用的單行上的dml語(yǔ)句,如果dml語(yǔ)句作用在多行上,則必須使用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通過(guò)使用bulk collect into子句處理動(dòng)態(tài)sql中的多行查詢可以加快處理速度,從而提高應(yīng)用程序的性能。當(dāng)使用bulk子句時(shí),集合類型可以是plsql所支持的索引表、嵌套表和varray,但集合元素必須使用sql數(shù)據(jù)類型。在oracle9i以后,有三種語(yǔ)句支持bulk子句,execute immediate,fetch和forall。
1、使用動(dòng)態(tài)游標(biāo)(游標(biāo)變量)處理多行查詢類動(dòng)態(tài)sql語(yǔ)句。
DECLARE TYPE ref_cur IS REF CURSOR; rc ref_cur; emprow emp%ROWTYPE; v_sql VARCHAR2(100):= 'select * from emp where deptno = :x'; --動(dòng)態(tài)執(zhí)行的SQL語(yǔ)句 BEGIN OPEN rc FOR v_sql USING 30; --打開游標(biāo),綁定執(zhí)行的SQL語(yǔ)句,并傳遞參數(shù) 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
示例:
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;
3、在forall語(yǔ)句中使用bulk collect into語(yǔ)句
示例:
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;
到此這篇關(guān)于Oracle中執(zhí)行動(dòng)態(tài)SQL的文章就介紹到這了。希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
詳解Oracle如何將txt文件中的數(shù)據(jù)導(dǎo)入數(shù)據(jù)庫(kù)
這篇文章主要介紹了Oracle如何將txt文件中的數(shù)據(jù)導(dǎo)入數(shù)據(jù)庫(kù),文中通過(guò)代碼示例和圖文結(jié)合的方式給大家講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-03-03Linux?CentOS7安裝Oracle11g的超完美新手教程
Linux下安裝Oracle相比windows安裝Oracle要顯得繁瑣很多,繁瑣在前期準(zhǔn)備工作很多,下面這篇文章主要給大家介紹了關(guān)于Linux?CentOS7安裝Oracle11g的超完美教程,需要的朋友可以參考下2022-07-07從Oracle數(shù)據(jù)庫(kù)中讀取數(shù)據(jù)自動(dòng)生成INSERT語(yǔ)句的方法
今天小編就為大家分享一篇關(guān)于從Oracle數(shù)據(jù)庫(kù)中讀取數(shù)據(jù)自動(dòng)生成INSERT語(yǔ)句的方法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-04-04Oracle數(shù)據(jù)庫(kù)系統(tǒng)使用經(jīng)驗(yàn)六則
Oracle數(shù)據(jù)庫(kù)系統(tǒng)使用經(jīng)驗(yàn)六則...2007-03-03在oracle 數(shù)據(jù)庫(kù)查詢的select 查詢字段中關(guān)聯(lián)其他表的方法
在實(shí)際開發(fā)過(guò)程中,特別是在做數(shù)據(jù)查詢的時(shí)候,能夠根據(jù)動(dòng)態(tài)生成的sql語(yǔ)句將查詢的結(jié)果轉(zhuǎn)化并返回到業(yè)務(wù)處理邏輯(或頁(yè)面展示出來(lái))能大大的減輕業(yè)務(wù)邏輯的處理復(fù)雜度。2009-08-08Oracle如何設(shè)置表空間數(shù)據(jù)文件大小
這篇文章主要介紹了Oracle如何設(shè)置表空間數(shù)據(jù)文件大小,文中講解非常細(xì)致,幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-07-07Oracle在DML語(yǔ)句中使用returing?into子句
這篇文章介紹了Oracle在DML語(yǔ)句中使用returing?into子句的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05Oracle 12C實(shí)現(xiàn)跨網(wǎng)絡(luò)傳輸數(shù)據(jù)庫(kù)詳解
這篇文章主要給大家介紹了關(guān)于Oracle 12C實(shí)現(xiàn)跨網(wǎng)絡(luò)傳輸數(shù)據(jù)庫(kù)的相關(guān)資料,文中介紹的非常詳細(xì),相信對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。2017-06-06