Oracle游標詳解


1、游標的概念

游標(CURSOR):游標是把從數據表中提取出來的數據,以臨時表的形式存放在內存中,在游標中有一個數據指針,在初始狀態下指向的是首記錄,利用fetch語句可以移動該指針,從而對游標中的數據進行各種操作。

2、游標的作用

游標是用來處理使用SELECT語句從數據庫中檢索到的多行記錄的工具。借助於游標的功能,數據庫應用程序可以對一組記錄逐條進行處理,每次處理一行。

3、游標的類型

  • 顯式游標(Explicit Cursor):顯式游標需要定義聲明,在使用前要打開和獲取,使用完畢后要關閉。多用於返回多行的SELECT語句
  • 隱式游標(Implicit Cursor):在執行一個SQL語句時,服務器將自動創建一個隱式游標,該游標是內存中的工作區,存儲了執行SQL語句的結果,可通過游標的屬性獲得SQL的執行結果及狀態信息。多用於只返回一行的SQL語句

4、隱式游標

(ORACLE在創建隱式游標時,默認的游標名為SQL)

  1)游標的主要屬性(顯示游標、隱式游標)

  • %FOUND 布爾型屬性,當SQL語句至少影響一行時為TRUE,否則為FALSE
  • %NOTFOUND 布爾型屬性,當SQL語句沒有影響的行時為TRUE,否則為FALSE
  • %ISOPEN 布爾型屬性,當游標已打開時返回TRUE,否則為FALSE(對用戶而言,隱式游標永遠是false)
  • %ROWCOUNT 數 字型屬性,返回受到SQL影響的行數

注意:
屬性名與游標名之間沒有空格。
游標的屬性只能在PL/SQL塊中使用,而不能在SQL語句中使用
例1 將PRODUCTS表中類型為1的所有產品的單價打9折,並顯示該更新所影響的行數.

BEGIN
   UPDATE products
   SET  unitprice=unitprice*0.9
   WHERE categoryid=1;
   IF SQL%FOUND THEN
      dbms_output.put_line(‘更新了’||SQL%ROWCOUNT||’條記錄’);
  ELSE
      dbms_output.put_line(‘沒有更新記錄’);
  END IF;
END;

5、顯式游標

 1)定義游標     

     在使用顯示游標之前,必須先在聲明部分定義游標,其定義語法如下:
        CURSOR cursor_name[(parameter,…)]
         IS select_statement;
  說明: 參數parameter形式如下:para_name [IN] data_type [:=|DEFAULT value]

(2)打開游標       

  當打開游標時,ORACLE會執行游標所對應的SELECT語句,並將結果存放到結果集,其定義語法如下:
  OPEN cursor_name[(parameter,…)];

(3)提取數據語法如下:  

   FETCH  cursor_name INTO variable[,…];
說明:

  • 對游標第一次執行FETCH語句時,它將工作區中的第一條記錄賦給賦給變量,並使工作區內的指針指向下一條記錄。
  • 工作區中的游標指針只能向下移動,不能回退。
  • 在使用FETCH語句之前,必須先打開游標,才能保證工作區內有數據。
  • INTO子句中的變量,順序、類型必須與工作區中每行記錄的字段數、順序以及數據類型一一對應

(4)關閉游標       

  關閉游標可釋放其結果集,語法如下:
      CLOSE  cursor_name;
   說明:關閉游標,就是使游標所對應的內存工作區變為無效,並釋放與游標相關的系統資源

顯式游標——無參游標

例2:用顯式游標顯示輸出products表中供應商編號為6 的產品的信息。

DECLARE
   CURSOR  prod_cursor  IS
     select *from products where
     supplierid=6;
  prod_record products%rowtype;
BEGIN
  OPEN prod_cursor;
  LOOP
   FETCH prod_cursor INTO prod_record;
EXIT WHEN
    prod_cursor%NOTFOUND;
dbms_output.put_line(‘產品編號’||prod_record.productid);
dbms_output.put_line(‘產品名稱’||prod_record.productname);
dbms_output.put_line(‘供應商編號’||prod_record.supplierid);
END LOOP;
CLOSE prod_cursor;
END;

顯式游標——參數游標

例3:用顯式參數游標顯示輸出products表中供應商編號為XX 的產品的信息。

DECLARE
   CURSOR  prod_cursor (suppID in number DEFAULT 1)  IS
     select * from products where
     supplierid=suppId;
  prod_record products%rowtype;
BEGIN
  OPEN prod_cursor(2);
  LOOP
   FETCH prod_cursor INTO prod_record;
EXIT WHEN
    prod_cursor%notfound;
dbms_output.put_line(‘產品編號’||prod_record.productid);
dbms_output.put_line(‘產品名稱’||prod_record.productname);
dbms_output.put_line(‘供應商編號’||prod_record.supplierid);
END LOOP;
CLOSE prod_cursor;
END;

注意:在為參數游標定義參數的數據類型時,不能使用長度約束

顯式游標——游標FOR循環

語法格式:
FOR 循環變量 IN 游標類型名
    LOOP
         循環語句
    END LOOP;
注意:

  • 循環變量不需要定義,系統隱含地定義其數據類型為%ROWTYPE的變量
  • 使用游標FOR循環時,不能使用OPEN、FETCH、CLOSE語句。

例4:用顯式參數游標顯示輸出products表中供應商編號為XX 的產品的信息。

DECLARE
   CURSOR  prod_cursor (suppID in number DEFAULT 1)  IS
     select *from products where    supplierid=suppId;
BEGIN
FOR v_pr IN prod_cursor(3) LOOP
dbms_output.put_line(‘產品編號’||v_pr.productid);
dbms_output.put_line(‘產品名稱’||v_pr.productname);
dbms_output.put_line(‘供應商編號’||v_pr.supplierid);
END LOOP;
END;

5.顯示游標與隱式游標比較

 6.游標變量

游標包括顯示游標和隱式游標,在定義時與特定的查詢綁定,即在聲明中定義查詢,其結構是不變的,因此又稱靜態變量。

游標變量是一個指向多行查詢結果集的指針,不與特定的查詢綁定,可以在打開游標變量時定義查詢,可以返回不同結構的結果集。

PL/SQL 中,使用游標變量包括定定義游標引用類型(REF CURSOR),聲明游標變量,打開游標變量、檢索游標變量、關閉游標變量等幾個基本步驟。     

游標變量基本步驟:

(1) 定義游標CURSOR類型的指針
 TYPE type_name IS REF CURSOR [RETURN return_type];
type_name 是新引用類型的名字
而return_type表示該游標變量返回的記錄類型。
(2) 聲明REF CURSOR類型的變量
    游標變量   type_name;

(3) 打開游標變量的語法格式如下所示:
   OPEN  游標變量名  FOR SELECT 語句;

(4) 檢索游標變量

 檢索游標變量的方法與檢索靜態游標相似,使用 FETCH.... INTO 語句循環檢索游標變量的
結果集中的記錄。語法為:

LOOP
FETCH cursor _ variable INTO variablel,variable2........;
EXIT WHEN Cursor_ variables%NOTFOUND;
........
END LOOP;

檢索游標變量時只能使用簡單循環或 WHILE 循環,不能采用 FOR 循環.

(5)關閉游標變量

檢索並處理完游標變量所對應的結果集后,可以關閉游標變量,釋放存儲空間。語法為;

close 游標變量名;

游標變量的不同定義方式舉例

DECLARE
  1-- 用 %ROWTYPE類型定義游標變量的返回值.
       TYPE t_productsRef IS REF CURSOR
        RETURN products%ROWTYPE;
  2-- 定義一個新的記錄類型
       TYPE t_prodRecord IS RECORD (
         prodid  products.productid%TYPE,
         prodname   products.productname%TYPE);
        --定義游標變量的返回值為記錄類型變量
       TYPE t_prodRef IS REF CURSOR
         RETURN  t_prodRecord;

例5:使用游標變量查詢出產品表中類別為1的產品的信息,並輸出產品名稱、類別編號、單價。

DECLARE
      TYPE prod_record IS RECORD
      ( pname products.productname%type,
        cid products.categoryid%type,
        uprice products.unitprice%type);
      TYPE prod_cursor IS REF CURSOR RETURN prod_reord;
      v_prodcur prod_cursor ;
      v_prodrec  prod_record;
BEGIN
   OPEN v_prodcur FOR select productname,categoryid,unitprice from products where categoryid=1;
  LOOP
FETCH v_prodcur INTO v_prodrec ;
 EXIT WHEN v_prodcur%notfound;
 dbms_output.put_line (‘產名’||v_prodrec.pname);
dbms_output.put_line(‘產品類別’||v_prodrec.cid);
dbms_output.put_line (‘單價’||v_prodrec.uprice);
  End  LOOP;
Close v_prodcur;
End; 

使用同一游標變量打開多個查詢
例6:使用游標變量查詢出產品表中類別為1的產品的信息,然后查詢輸出產品單價小於20的產品信息。

DECLARE
TYPE prod_cursor IS REF CURSOR;
      v_cur prod_cursor;
      v_rec products%rowtype;
BEGIN
   OPEN v_cur FOR select *  from products where categoryid=1;
  LOOP
     FETCH v_cur INTO v_rec;
     EXIT WHEN v_cur%notfound;
     dbms_output.put_line('產品名' || v_rec.productname);
     dbms_output.put_line('產品類別' || v_rec.categoryid);
     dbms_output.put_line('單價' || v_rec.unitprice);
  End  LOOP;
OPEN v_cur FOR select *  from products where unitprice<20;
  LOOP
     FETCH v_cur INTO v_rec;
 EXIT WHEN v_cur%notfound;
    dbms_output.put_line('產品名' || v_rec.productname);
    dbms_output.put_line('產品類別' || v_rec.categoryid);
     dbms_output.put_line('單價' || v_rec.unitprice);
  End  LOOP;
Close v_cur;
End;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM