oracle動態sql和靜態sql比較
1.靜態sqlsql與動態sql
oracle編譯pl/sql程式塊分為兩個種:其一為前期聯編(early binding),即sql語句在程式編譯期間就已經確定,大多數的編譯情況屬於這種型別;另外一種是後期聯編(late binding),即sql語句只有在執行階段才能建立,例如當查詢條件為使用者輸入時,那麼oracle的sql引擎就無法在編譯期對該程式語句進行確定,只能在使用者輸入一定的查詢條件後才能提交給sql引擎進行處理。通常,靜態sql採用前一種編譯方式,而動態sql採用後一種編譯方式。
2.動態sql程式開發
理解了動態sql編譯的原理,也就掌握了其基本的開發思想。動態sql既然是一種」不確定」的sql,那其執行就有其相應的特點。oracle中提供了execute immediate語句來執行動態sql,語法如下:
excute immediate 動態sql語句 using 繫結引數列表 returning into 輸出引數列表;對這一語句作如下說明:
1)動態sql是指ddl和不確定的dml(即帶引數的dml)
2)繫結引數列表為輸入引數列表,即其型別為in型別,在執行時刻與動態sql語句中的引數(實際上佔位符,可以理解為函式裡面的形式引數)進行繫結。
3)輸出引數列表為動態sql語句執行後返回的引數列表。
4)由於動態sql是在執行時刻進行確定的,所以相對於靜態而言,其更多的會損失一些系統效能來換取其靈活性。
為了更好的說明其開發的過程,下面列舉乙個例項:
設資料庫的他表,其資料為如下:
idname
sal10
scott
3000
20tom
5000
30jerry
4500
要求:
1.建立該錶並輸入相應的資料。
2.根據特定id可以查詢到其姓名和薪水的資訊。
3.根據大於特定的薪水的查詢相應的員工資訊。
根據前面的要求,可以分別建立三個過程(均使用動態sql)來實現:
過程一:(建立表並插入資料)
18:16:27 scott@ prod>create or replace procedure p1 as18:16:36 2 flag number;
18:16:36 3 begin
18:16:36 4 select count(*) into flag from all_tables where table_name='t1';
18:16:36 5 if (flag=0) then
18:16:36 6 execute immediate 'create table t1(id number,name varchar2(10),sal number)';
18:16:36 7 else
18:16:36 8 insert into t1 values (10,'scott',3000);
18:16:36 9 insert into t1 values (20,'tom',5000);
18:16:37 10 insert into t1 values (30,'jerry',4500);
18:16:37 11 end if;
18:16:37 12 end p1;
18:16:38 13 /
procedure created.
elapsed: 00:00:00.20
18:16:40 scott@ prod>exec p1;
pl/sql procedure successfully completed.
elapsed: 00:00:00.18
18:16:47 scott@ prod>select * from t1;
id name sal
---------- ---------- ----------
10 scott 3000
20 tom 5000
30 jerry 4500
elapsed: 00:00:00.01
18:16:52 scott@ prod>
過程二:(按id查詢使用者資訊)
18:40:24 scott@ prod>create or replace procedure p2 (p_id number) as18:40:26 2 v_name varchar2(10);
18:40:26 3 v_sal number;
18:40:26 4 begin
18:40:26 5 execute immediate 'select name,sal from t1 where id=:1' into v_name,v_sal using p_id;
18:40:26 6 dbms_output.put_line(v_name ||' salary is: '||to_char(v_sal));
18:40:26 7 exception
18:40:26 8 when others then
18:40:26 9 dbms_output.put_line('no data found');
18:40:26 10 end p2;
18:40:26 11 /
procedure created.
elapsed: 00:00:00.07
18:40:27 scott@ prod>exec p2(10);
scott salary is: 3000
pl/sql procedure successfully completed.
elapsed: 00:00:00.01
18:40:32 scott@ prod>exec p2(20);
tom salary is: 5000
pl/sql procedure successfully completed.
elapsed: 00:00:00.02
18:40:40 scott@ prod>exec p2(30);
jerry salary is: 4500
pl/sql procedure successfully completed.
elapsed: 00:00:00.02
18:40:45 scott@ prod>
過程三:(查詢薪水大於某個值的員工)
18:48:59 scott@ prod>create or replace procedure p3(p_sal number) as18:50:55 2 r_t1 t1%rowtype;
18:50:55 3 type c_type is ref cursor;
18:50:56 4 c1 c_type;
18:50:56 5 begin
18:50:56 6 open c1 for '
18:50:56 7 select * from t1
18:50:56 8 where sal >:1'
18:50:56 9 using p_sal;
18:50:56 10 loop
18:50:56 11 fetch c1 into r_t1;
18:50:56 12 exit when c1%notfound;
18:50:56 13 dbms_output.put_line('salary higher '||to_char(p_sal)||' name is:');
18:50:56 14 dbms_output.put_line('id is ' ||to_char(r_t1.id)||' name is: '||r_t1.name);
18:50:56 15 end loop;
18:50:56 16 close c1;
18:50:56 17 end p3;
18:50:57 18 /
procedure created.
elapsed: 00:00:00.12
18:50:58 scott@ prod>exec p3(2000);
salary higher 2000 name is:
id is 10 name is: scott
salary higher 2000 name is:
id is 20 name is: tom
salary higher 2000 name is:
id is 30 name is: jerry
pl/sql procedure successfully completed.
elapsed: 00:00:00.02
18:51:15 scott@ prod>
注意:在過程二中的動態sql語句使用了佔位符「:1「,其實它相當於函式的形式引數,使用」:「作為字首,然後使用using語句將p_id在執行時刻將:1給替換掉,這裡p_id相當於函式裡的實參。另外過程三中開啟的游標為動態游標,它也屬於動態sql的範疇,其整個編譯和開發的過程與execute immediate執行的過程很類似。
本文出自 「天涯客的blog」 部落格,請務必保留此出處
動態sql 和靜態sql 下篇
動態sql 和靜態sql 下篇 1 批量繫結讓oracle 在對一組值進行sql操作時繫結乙個變數,這一組資料可以是任何的plsql的聚合型別 聯合陣列,內嵌表,可變陣列 集合元素必須是sql的資料型別,比如char date mumber。有三個句法支援動態批量繫結,execute immedia...
ORACLE 動態註冊和靜態註冊的區別
1,oracle 10g 用netca方式建立的都預設為動態註冊方式 listener description list description address protocol tcp host r1 port 1521 address protocol ipc key extproc0 3,兩者...
動態對映和靜態對映
先說virtualalloc和virtualcopy virtualalloc 首先會從我們的虛擬位址空間中申請 或者說預留 一塊虛擬空間,準備接下來要用它。注意此時,可用的物理記憶體並沒有減少,只是虛擬位址少了一塊可用的區域。真正把這塊之前 reserved 的虛擬空間對映到物理的記憶體區域就是由...