oracle游標使用

2021-07-31 16:28:18 字數 3240 閱讀 2653

在進行pl/sql程式設計時,我們都會使用游標,游標有兩種,一種是顯式游標,使用類似如下方式:

open 游標

loop

fetch into …;

exit when notfound;

end loop;

close 游標;

另一種是隱式游標,使用類似如下:

for 游標變數 in 游標

loop

賦值變數:=游標變數.列;

end loop;

這兩種游標究竟何種效能更高,消耗資源更小呢?

我們先來做乙個測試,下面分別為兩種型別游標的測試**:

顯式游標**:

declare

v_begin number(10);

v_end number(10);

v_currtime number(12,2);

v_usetime number(12,2);

v_owner dba_objects.owner%type;

v_object_name dba_objects.object_name%type;

v_object_type dba_objects.object_type%type;

cursor get_obj is

select owner,object_name,object_type from dba_objects;

begin

select

value

into v_begin from v$sess_time_model where sid=sys_context('userenv','sid') and stat_name='db cpu';

v_currtime:=dbms_utility.get_time;

open get_obj;

loop

fetch get_obj into v_owner,v_object_name,v_object_type;

exit when get_obj%notfound;

end loop;

v_usetime:=(dbms_utility.get_time-v_currtime)/100;

dbms_lock.sleep(15);

select

value

into v_end from v$sess_time_model where sid=sys_context('userenv','sid') and stat_name='db cpu';

dbms_output.put_line('耗時:'||to_char(v_usetime,'0.00')||'秒,cpu消耗次數:'||to_char(v_end-v_begin));

close get_obj;

exception

when others then

close get_obj;

raise;

end;

隱式游標**:

declare

v_begin number(10);

v_end number(10);

v_currtime number(12,2);

v_usetime number(12,2);

v_owner dba_objects.owner%type;

v_object_name dba_objects.object_name%type;

v_object_type dba_objects.object_type%type;

cursor get_obj is

select owner,object_name,object_type from dba_objects;

begin

select

value

into v_begin from v$sess_time_model where sid=sys_context('userenv','sid') and stat_name='db cpu';

v_currtime:=dbms_utility.get_time;

for get_obj_cur in get_obj

loop

v_owner:=get_obj_cur.owner;

v_object_name:=get_obj_cur.object_name;

v_object_type:=get_obj_cur.object_type;

end loop;

v_usetime:=(dbms_utility.get_time-v_currtime)/100;

dbms_lock.sleep(15);

select

value

into v_end from v$sess_time_model where sid=sys_context('userenv','sid') and stat_name='db cpu';

dbms_output.put_line('耗時:'||to_char(v_usetime,'0.00')||'秒,cpu消耗次數:'||to_char(v_end-v_begin));

end;

**說明:

兩段**的功能完全一樣,都只是對dba_objects檢視作了一次迴圈,通過dbms_utility.get_time差獲取執行時間(單位:百分之一秒),通過$sess_time_model檢視獲取執行緒消耗的cpu次數,由於$sess_time_model每15秒重新整理一次,因此,為保證執行完成後獲取到的cpu消耗次數準確,通過dbms_lock.sleep方法,等待15秒。

執行結果:

顯式游標方式:耗時: 2.68秒,cpu消耗次數:2687500

隱工游標方式:耗時: 0.62秒,cpu消耗次數:625000

即顯式游標無論是執行效能還是對cpu資源的消耗,都明顯高於隱式游標,隱式游標的效能比顯式游標高4倍以上。

分析:

變數的綁入與綁出需要消耗大量的cpu資源,顯式游標每fetch一次就執行一次輸出變數繫結,而在執行隱式游標時,oracle作了乙個類似於fetch bulk 的輸出優化,所以效能及cpu消耗可以大幅提高。

因此,建議大家,在需要用到游標的情況下,永遠不要使用逐行fetch的輸出方式,盡可能使用cursor for loop的隱式游標方式。

oracle 游標使用

create or replace function errortyperead return varchar2 is result varchar2 3000 type cursor type is ref cursor tempname varchar2 100 cursor testcur i...

Oracle游標使用

一,什麼是游標 遍歷查詢結果集的一種機制。二,為什麼避免使用游標 盡量避免使用游標,因為游標的效率較差 如果使用了游標,就要盡量避免在游標迴圈中再進行表連線的操作。三,使用游標的步驟 靜態游標 1,宣告一些變數,用來儲存游標遍歷過程的臨時資料 2,宣告游標,並且指定查詢 3,開啟游標 4,從游標中獲...

oracle游標使用

游標 用來查詢資料庫,獲取記錄集合 結果集 的指標,可以讓開發者一次訪問一行結果集,在每條結果集上作操作。分類 靜態游標 分為顯式游標和隱式游標。ref游標 是一種引用型別,類似於指標。顯式游標 cursor 游標名 引數 返回值型別 is select 語句 生命週期 1.開啟游標 open 解析...