本文簡單的列舉了pl/sql中用到的幾種不同型別的游標寫法,並簡單對比了不同游標寫法的優缺點,同時給出了乙個選擇的基本原則。
pl/sql裡的游標可以分為顯式和隱式兩種,而隱式有分為select into隱式游標和for .. in 隱式游標兩種。所以,我們可以認為,有3種游標用法:
a. 顯式游標
b. select into隱式游標
c. for .. in 隱式游標
a. 顯式游標
普通顯式游標,指的是通過定義獲得游標,並通過open,fetch,close的等方法來操作
游標
bulk collect的 顯式游標php code:
declare
cursor c is select tname from tab
; l_tname varchar2(64
);begin
open c
; loop
fetch c into l_tname
; exit
when c
%notfound
;
dbms_output
.put_line
(l_tname
);end loop
;close c
;end;/
....
bulk collect的 顯式游標 + limitphp code:
declare
cursor c is select tname from tab
;l_tname_array dbms_sql
.varchar2_table
;begin
open c
;fetch c bulk collect into l_tname_array
;for
i in 1
.. l_tname_array
.count loop
dbms_output
.put_line
(l_tname_array(i
) );
end loop
;close c
;end;/
....
php code:
declare
cursor c is select tname from tab
;l_tname_array dbms_sql
.varchar2_table
;begin
open c
;loop
fetch c bulk collect into l_tname_array limit 10
;exit
when c
%notfound
; for
i in 1
.. l_tname_array
.count loop
dbms_output
.put_line
(l_tname_array(i
) );
end loop
;end loop
;close c
;end;/
....
動態sql 的 select into隱式游標
隱式游標相對於顯式游標而言,指的是不需要事先declare,也無須用open,fetch,close的等方法來操作,而是通過其它的方式來操作游標
b. select into隱式游標
php code:
declare
l_tname varchar2
(100
);begin
select tname into l_tname from tab where rownum
= 1
;dbms_output
.put_line
(l_tname
);end;/
....
動態sql 的 select into隱式游標 + bulk collectphp code:
declare
l_tname varchar2
(100
);l_table_name varchar2
(100
);l_sql varchar2
(200
);begin
l_table_name
:= 'tab'
;l_sql
:= 'select tname from '
||l_table_name
||' where rownum = 1 '
;execute immediate l_sql into l_tname
;
dbms_output
.put_line
(l_tname
);end;/
....
c. for .. in 隱式游標php code:
declare
l_tname_array dbms_sql
.varchar2_table
;l_table_name varchar2
(100
);l_sql varchar2
(200
);begin
l_table_name
:= 'tab'
;l_sql
:= 'select tname from '
||l_table_name
;execute immediate l_sql bulk collect into l_tname_array
;for
i in 1
.. l_tname_array
.count loop
dbms_output
.put_line
(l_tname_array(i
) );
end loop
;end;/
....
for .. in 隱式游標通過loop的開始於結束來控制cursor的open與close.
2.三種用法的優劣php code:
begin
for
c in
(select tname from tab
) loop
dbms_output
.put_line(c
.tname
);end loop
;end;/
....
a. 顯式游標
優點:
·可以用於bulk collect的批量處理句式以提高效能
·可以用於動態sql的游標處理
缺點:
·麻煩,需要定義,開啟,fetch,close一堆**,增加**複雜度,從而增加出錯的可能性
b. select into隱式游標b
優點
·**量最少
·可以自動detect 返回資料超過一行或少於一行的錯誤
·可以使用bulk collect 批量處理,但是無法使用limit 關鍵字
缺點
·如果不使用bulk collect 批量處理,僅僅只能用於返回資料正好一行的情況,無法使用於返回資料超過一行或少於一行的環境
·使用bulk collect 批量處理時,無法使用limit 關鍵字,無法處理返回行數太多的情況(不好處理,容易造成pga過大)
c. for .. in 隱式游標
優點
·**量遠少於顯式游標
·**可讀性優於顯式游標
·**的出錯可能性也小於顯式游標
缺點:
·無法用於動態sql的游標處理
·在返回行數超過10行的情況下,效能明顯不如使用bulk collect的顯式游標
在效能對比方面,除非是使用了bulk collect,否則,三種方式沒有明顯效能差距。
3。具體的選擇
·在返回資料為一行的情況下,盡量使用select into 的隱式游標
·返回0行或者《幾十行的情況下,使用for .. in 隱式游標
·或者在返回行稍多,但是不關心fetch效能的情況下,也可考慮用for .. in 隱式游標
·返回10行-100行(乙個很隨意選擇的經驗值,可以自己根據情況設定),而且關心fetch效能的情況下,可以使用select into 的隱式游標+bulk collect ,在獲得效能提公升的情況下,**量也不會增加太多。
·返回行數很多,> 100, 應選用顯示游標+bulk collect ,以獲得較高的fetch 效能,同時不至於使用太大的pga記憶體。
·如國使用動態sql, 則根據select list (column list) 是否固定,如果固定,仍然可以考慮使用select into 的隱式游標+動態sql的方式。當然,仍然需要考慮返回行數的問題。
·如果select list (column list) 不固定,則只好使用顯式游標
·或者動態語句返回行數太多,必須用limit,那麼也只好用顯式游標了。
PL SQL中的游標
游標是對映在結果集中一行資料上的位置實體,有了游標,使用者就可以訪問結果集中的任意一行資料了,將游標放置到某行後,即可對該行資料進行操作,例如提取當前行的資料等。oracle 游標有4個屬性 isopen,found,notfound,rowcount。isopen判斷游標是否被開啟,如果開啟 is...
PL SQL中的游標
為了處理 sql 語句,oracle 必須分配一片叫上下文 context area 的區域來處理所必需的資訊,其中包括要處理的行的數目,乙個指向語句被分析以後的表示形式的指標以及查詢的活動集 active set 游標是乙個指向上下文的控制代碼 handle 或指標。通過游標,pl sql可以控制...
如何正確選擇聚類演算法?
本文將介紹四種基本的聚類演算法 層次聚類 基於質心的聚類 最大期望演算法和基於密度的聚類演算法,並討論不同演算法的優缺點。聚類演算法十分容易上手,但是選擇恰當的聚類演算法並不是一件容易的事。資料聚類是搭建乙個正確資料模型的重要步驟。資料分析應當根據資料的共同點整理資訊。然而主要問題是,什麼通用性引數...