游標(biāo)的使用

一、簡(jiǎn)介

1、游標(biāo)的概念

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

2、游標(biāo)的分類

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

二、顯式游標(biāo)

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

1、使用步驟

1)、聲明游標(biāo)

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

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

OPEN cursor_name;

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

FETCH cursor_name INTO v_name;

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

CLOSE cursor_name;

2、示例

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

3、顯示游標(biāo)的屬性

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

IF cur_product%ISOPEN  THEN
    ...                            --游標(biāo)已打開執(zhí)行的語(yǔ)句
ELSE 
  OPEN cur_product;                --游標(biāo)未打開則打開游標(biāo)
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  ||  '價(jià)格:' ||   v_price);
    ELSE
        EXIT;
    END IF;
END LOOP;

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

4、使用 FETCH ... BULK COLLECT INTO 語(yǔ)句提取全部數(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  ||  '價(jià)格:' ||   product_tab(i).price);
      END LOOP;
  CLOSE cur_product;
  
end;

5、使用 FETCH ... BULK COLLECT INTO LIMIT語(yǔ)句提取部分?jǐn)?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  ||  '價(jià)格:' ||   product_tab(i).price);
           END LOOP;
               DBMS_OUTPUT.PUT_LINE('-------');
       EXIT WHEN cur_product%NOTFOUND;
       END LOOP;
  CLOSE cur_product;
  
end;

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

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

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

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

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

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

參數(shù)游標(biāo)的定義:
    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);            --打開游標(biāo)時(shí)傳入?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;

三、隱式游標(biāo)

1、隱式游標(biāo)的特點(diǎn)

隱式游標(biāo)是PL/SQL自動(dòng)管理的,有以下特點(diǎn):
1)隱式游標(biāo)有默認(rèn)名稱:SQL
2)每當(dāng)運(yùn)行SELECT語(yǔ)句或者DML語(yǔ)句時(shí),PL/SQL會(huì)打開一個(gè)隱式游標(biāo)
3)隱式游標(biāo)屬性值始終是最新執(zhí)行的SQL語(yǔ)句的

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、隱式游標(biāo)的屬性

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

四、REF游標(biāo)

REF CURSOR是一個(gè)游標(biāo)變量,當(dāng)使用顯式游標(biāo)時(shí),必須在定義部分指定其對(duì)應(yīng)的select語(yǔ)句,而使用REF CURSOR時(shí),可以在打開游標(biāo)時(shí)指定其對(duì)應(yīng)的select語(yǔ)句.

1、使用步驟

1)、定義REF CURSOR類型、游標(biāo)變量

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

2)、打開游標(biāo)

OPEN cur_name FOR select_statement;

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

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類型時(shí)指定了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)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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

友情鏈接更多精彩內(nèi)容