PL SQL 中如何正確選擇游標型別

2021-05-26 22:13:33 字數 4996 閱讀 2226

本文簡單的列舉了pl/sql中用到的幾種不同型別的游標寫法,並簡單對比了不同游標寫法的優缺點,同時給出了乙個選擇的基本原則。

pl/sql裡的游標可以分為顯式和隱式兩種,而隱式有分為select into隱式游標和for .. in 隱式游標兩種。所以,我們可以認為,有3種游標用法:

a. 顯式游標

b. select into隱式游標

c. for .. in 隱式游標

a. 顯式游標

普通顯式游標,指的是通過定義獲得游標,並通過open,fetch,close的等方法來操作

游標

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的 顯式游標
php 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;/

....

bulk collect的 顯式游標 + limit
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;/

....

隱式游標相對於顯式游標而言,指的是不需要事先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隱式游標

php 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;/

....

動態sql 的 select into隱式游標 + bulk collect

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;/

....

c. for .. in 隱式游標

for .. in 隱式游標通過loop的開始於結束來控制cursor的open與close.

php code:

begin

for 

c in 

(select tname from tab

) loop

dbms_output

.put_line(c

.tname

);end loop

;end;/

....

2.三種用法的優劣

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可以控制...

如何正確選擇聚類演算法?

本文將介紹四種基本的聚類演算法 層次聚類 基於質心的聚類 最大期望演算法和基於密度的聚類演算法,並討論不同演算法的優缺點。聚類演算法十分容易上手,但是選擇恰當的聚類演算法並不是一件容易的事。資料聚類是搭建乙個正確資料模型的重要步驟。資料分析應當根據資料的共同點整理資訊。然而主要問題是,什麼通用性引數...