游標的使用

一、簡介

1、游標的概念

游標(Cursor) 就是一個變動的光標,它本質(zhì)上是一個指針,指向從數(shù)據(jù)庫查詢出來的結(jié)果集任何一條記錄,初始的時候指向第一條記錄。

2、游標的分類

Oracle中游標分為兩類:普通游標、REF游標,普通游標又可以分為兩種類型:顯式游標、隱式游標.

二、顯式游標

顯式游標是指在使用前必須有著明確的游標聲明和定義,顯式游標的定義會關(guān)聯(lián)查詢語句,返回一條或多條記錄,顯示游標的使用由開發(fā)人員控制。

1、使用步驟

1)、聲明游標

CURSOR cursor_name                  --聲明游標,cursor_name是游標名稱
    is select_statement;            --游標關(guān)聯(lián)的select語句,注意:不能是select ... into 語句

2)、打開游標
游標中想要讀取數(shù)據(jù)都是建立在游標已打開的前提下

OPEN cursor_name;

3)、讀取數(shù)據(jù)
讀取數(shù)據(jù)是使用 FETCH語句,它可以把游標指向的行記錄數(shù)據(jù)提取出來賦值給聲明的變量,注意:FETCH語句只能取出當前行的記錄,一般情況下, FETCH語句 都是搭配 循環(huán)語句 一起使用,直到某個條件不符合退出循環(huán).

FETCH cursor_name INTO v_name;

4)、關(guān)閉游標

CLOSE cursor_name;

2、示例

示例1:
declare 
  CURSOR cur_product                                --1、聲明游標
        is select * from product;              
  v_row_product      product%rowtype;               --聲明product表的行變量     
 
begin
  OPEN cur_product;                                 --2、打開游標
       LOOP
          FETCH cur_product INTO v_row_product;     --3、讀取數(shù)據(jù)放入行變量
       EXIT  WHEN cur_product%NOTFOUND;
          DBMS_OUTPUT.PUT_LINE('商品名:'    ||  v_row_product.name  ||  '價格:' ||   v_row_product.price);
       END LOOP;
  CLOSE cur_product;                                --4、關(guān)閉游標  
end;


示例2:
declare 
  CURSOR cur_product
        is select name, price from product;
  v_name     product.name%type;
  v_price    product.price%type;
 
begin
  OPEN cur_product;
       LOOP
          FETCH cur_product INTO v_name, v_price;
       EXIT  WHEN cur_product%NOTFOUND;
          DBMS_OUTPUT.PUT_LINE('商品名:'    ||  v_name  ||  '價格:' ||   v_price);
       END LOOP;
  CLOSE cur_product;
end;

3、顯示游標的屬性

顯示游標的屬性用于返回其執(zhí)行信息,包括:
1)ISOPEN:獲取游標是否打開,已打開返回true,沒有打開返回false

IF cur_product%ISOPEN  THEN
    ...                            --游標已打開執(zhí)行的語句
ELSE 
  OPEN cur_product;                --游標未打開則打開游標
END IF;

2)FOUND:檢查是否從結(jié)果集中提取到了數(shù)據(jù),提取到返回true,否則返回false

LOOP
    FETCH cur_product INTO v_name, v_price;
    IF cur_product%FOUND;
        DBMS_OUTPUT.PUT_LINE('商品名:'    ||  v_name  ||  '價格:' ||   v_price);
    ELSE
        EXIT;
    END IF;
END LOOP;

3)NOTFOUND:和FOUND相反,提取到數(shù)據(jù)返回false,未提取到數(shù)據(jù)返回true
4)ROWCOUNT:返回當前已經(jīng)提取了多少行數(shù)據(jù)

4、使用 FETCH ... BULK COLLECT INTO 語句提取全部數(shù)據(jù)

declare 
  CURSOR cur_product 
         is select * from product;
 
  TYPE product_tab_type IS TABLE OF product%rowtype;
  product_tab  product_tab_type;

begin
  OPEN cur_product;
      FETCH cur_product BULK COLLECT INTO product_tab;       --將數(shù)據(jù)全部提取出來放入product_tab
      FOR i in 1..product_tab.count LOOP                     --循環(huán)遍歷product_tab
           DBMS_OUTPUT.PUT_LINE('商品名:'    ||  product_tab(i).name  ||  '價格:' ||   product_tab(i).price);
      END LOOP;
  CLOSE cur_product;
  
end;

5、使用 FETCH ... BULK COLLECT INTO LIMIT語句提取部分數(shù)據(jù)

declare 
  CURSOR cur_product 
         is select * from product;
 
  TYPE product_tab_type IS TABLE OF product%rowtype;
  product_tab  product_tab_type;

begin
  OPEN cur_product;
       LOOP                                          --循環(huán)1:每次提取3行數(shù)據(jù)放入product_tab
           FETCH cur_product BULK COLLECT INTO product_tab LIMIT 3;
           FOR i in 1..product_tab.count LOOP        --循環(huán)2:遍歷輸出product_tab中的3行數(shù)據(jù)
               DBMS_OUTPUT.PUT_LINE('商品名:'    ||  product_tab(i).name  ||  '價格:' ||   product_tab(i).price);
           END LOOP;
               DBMS_OUTPUT.PUT_LINE('-------');
       EXIT WHEN cur_product%NOTFOUND;
       END LOOP;
  CLOSE cur_product;
  
end;

6、游標FOR循環(huán)

游標的使用大部分是為了迭代結(jié)果集,在PL/SQL中有一種更方便的循環(huán)游標的方式實現(xiàn)

declare 
  CURSOR cur_product 
         is select * from product;
 
begin
  FOR cur_info in cur_product      --將游標返回的數(shù)據(jù)放入cur_info ,該變量是%rowtype類型,并且無需聲明
  LOOP
      DBMS_OUTPUT.PUT_LINE('商品名:'    ||  cur_info.name  ||  '價格:' ||  cur_info.price);
  END LOOP;
end;

這種方式簡化了對游標的處理,使用這種情況時,Oracle會隱式地打開游標、提取數(shù)據(jù)、關(guān)閉游標.

7、帶參數(shù)的游標

使用顯示游標時可以指定參數(shù),參數(shù)可以傳遞給游標在查詢語句中使用.

參數(shù)游標的定義:
    cursor cursor_name              
        (param_name datatype, ...)
        is select_statement;        

示例:

declare 
  v_cid  product.cid%type := '1';  

  CURSOR cur_product
         (param_id varchar2)           --指定參數(shù)
         is select * from product where cid = param_id;    --使用參數(shù)
  
  v_row_product    product%rowtype; 

begin
  OPEN cur_product(v_cid);            --打開游標時傳入?yún)?shù)
  LOOP
      FETCH cur_product INTO v_row_product;
      EXIT WHEN cur_product%NOTFOUND;
      DBMS_OUTPUT.PUT_LINE(v_row_product.name);
  END LOOP;
  CLOSE cur_product;
end;

三、隱式游標

1、隱式游標的特點

隱式游標是PL/SQL自動管理的,有以下特點:
1)隱式游標有默認名稱:SQL
2)每當運行SELECT語句或者DML語句時,PL/SQL會打開一個隱式游標
3)隱式游標屬性值始終是最新執(zhí)行的SQL語句的

declare 
  v_name  product.name%type;  

begin
  select p.name into v_name from product p where p.pid = '1';
  IF SQL%FOUND THEN
     DBMS_OUTPUT.PUT_LINE('pid為666的商品名稱為:' || v_name);
  END IF;
end;

2、隱式游標的屬性

隱式游標屬性名稱和顯式游標一樣,不過其含義有區(qū)別
1)ISOPEN:由Oracle控制,永遠返回false
2)FOUND:反應(yīng)DML語句是否影響了數(shù)據(jù),有影響時返回true,否則返回false;也可以反應(yīng)SELECT INTO語句是否返回了數(shù)據(jù),返回了數(shù)據(jù)則該屬性值為true
3)NOTFOUND:和FOUND相反,DML語句沒有影響數(shù)據(jù)或SELECT INTO語句沒有返回數(shù)據(jù)時值為true,其它false
4)ROWCOUNT:反應(yīng)DML語句影響數(shù)據(jù)的數(shù)量

四、REF游標

REF CURSOR是一個游標變量,當使用顯式游標時,必須在定義部分指定其對應(yīng)的select語句,而使用REF CURSOR時,可以在打開游標時指定其對應(yīng)的select語句.

1、使用步驟

1)、定義REF CURSOR類型、游標變量

TYPE ref_type IS REF CURSOR [RETURN return_type];      --定義REF CURSOR類型
cur_name    type_type;                                 --聲明游標變量

2)、打開游標

OPEN cur_name FOR select_statement;

3)、提取數(shù)據(jù):和顯式游標使用方法一樣
4)、關(guān)閉游標:和顯式游標使用方法一樣

2、示例

declare 
  v_name  product.name%type;  

  TYPE ref_type IS REF CURSOR;
  cur_product ref_type;
  
begin
  OPEN cur_product FOR select p.name from product p;
  LOOP
       FETCH cur_product INTO v_name;
       EXIT WHEN cur_product%NOTFOUND;
       DBMS_OUTPUT.PUT_LINE(v_name);
  END LOOP;
  CLOSE cur_product;
end;

3、指定RETURN子句

如果在定義REF CURSOR類型時指定了RETURN 子句,那么在select_statement中返回的結(jié)果必須與RETURN 子句定義的記錄類型匹配.

declare 
  v_row_product  product%rowtype;  

  TYPE ref_type IS REF CURSOR RETURN product%rowtype;
  cur_product ref_type;
  
begin
  OPEN cur_product FOR select * from product p;      --必須是product%rowtype類型
  LOOP
       FETCH cur_product INTO v_row_product;
       EXIT WHEN cur_product%NOTFOUND;
       DBMS_OUTPUT.PUT_LINE(v_row_product.name);
  END LOOP;
  CLOSE cur_product;
end;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,443評論 6 532
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,530評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,407評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,981評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,759評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,204評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,263評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,415評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,955評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,650評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,892評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,675評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,967評論 2 374

推薦閱讀更多精彩內(nèi)容

  • 1.1 基本結(jié)構(gòu) PL/SQL程序由三個塊組成,即聲明部分、執(zhí)行部分、異常處理部分。 1.2 命名規(guī)則 1.3 記...
    慢清塵閱讀 3,871評論 3 14
  • oracle存儲過程常用技巧 我們在進行pl/sql編程時打交道最多的就是存儲過程了。存儲過程的結(jié)構(gòu)是非常的簡單的...
    dertch閱讀 3,501評論 1 12
  • 游標概念 由select語句返回的結(jié)果集包括滿足該語句的where子句中條件的所有行。但是有時候應(yīng)用程序并不總能將...
    不知名的蛋撻閱讀 2,040評論 0 6
  • 很多人隨著年齡的增長,除卻自己經(jīng)常聯(lián)系的朋友和家人,很少再會和其它人保持聯(lián)系,長此以往養(yǎng)成了一個不太好的習慣...
    熙熙Breathe閱讀 321評論 0 2
  • 我們的夏天,正好醞釀著一場雨。 你的自行車后座和我手中的冰棍,成了一道風景。 窗外,你穿著球衣的身影,映著夕陽的余...
    岐途和歧途閱讀 162評論 0 1