1. 程式人生 > >Session Cursor的種類和用法

Session Cursor的種類和用法

Oracle資料庫裡的Session Cursor 又細分為三種類型,分別是 **隱式遊標(Implicit Cursor)、 顯示遊標(explicit Cursor) 參考遊標(ref cursor)**

隱式遊標:

隱式遊標是Oracle中最常見的遊標,當我們執行sql 或者plsql時,Oracle都會自動幫我們建立隱式遊標。之所以稱為隱式遊標,是因為它的生命週期: open parse bind exectue fetch close全部是由sql引擎或者plsql引擎自動完成的。

Oracle資料庫的隱式遊標有以下四種: SQL%FOUND SQL%NOTFOUND SQL%ISOPEN SQL%ROWCOUNT

SQL%FOUND 表示一條sql語句被執行成功後,受其影響而改變的記錄數是否大於等於1. 因此SQL%FOUND通常用於執行INSERT UPDATE DELETE 和SELECT INTO。

在一條DML語句在執行之前 SQL%FOUND的值為NULL,當這條sql語句執行成功以後,如果改變的記錄條數大於等於1,那麼SQL%FOUND的值為true。否則為false。

當使用SELECT INTO時,當且僅當對應的SELECT 語句的返回結果只有一條記錄時,SQL%FOUND的值才是true。當返回的結果為0時,Oracle會報錯: NO_DATA_FOUND ,如果SELECT INTO返回的結果大於1,則Oracle會報錯“TOO_MANY_ROWS”.

SQL%NOTFOUND 表示一條sql語句被執行成功之後,受其影響而改變的記錄數是否為0,如果是0,那麼SQL%NOTFOUND的值為true,否則為false。

SQL%OPEN 表示隱式遊標是否處於開啟狀態。對於隱式遊標而言 其值永遠為false。

SQL%ROWCOUNT 表示一條sql語句成功執行後,受其影響而改變的記錄的數量。

當SELECT INTO語句返回超過一條以上的記錄時,Oracle會報錯 TOO_MANY_ROWS,這種情況下SQL%ROWCOUNT的值1,而不是SELECT INTO語句所有對應的SELECT返回的記錄數。

顯示遊標(Explicit Cursor)是Oracle資料庫中另外一種型別的Session Cursor,它通常用於plsql程式碼,之所以成為“顯示遊標”,是因為其定義和宣告週期管理中的OPEN FETCH CLOSE均由我們在plsql中控制。

Oracle的顯示遊標也有四個如下屬性: (CURSORNAME是我們在plsq程式碼中自定義的顯示遊標的名稱)

CURSORNAME%FOUND CURSORNAME%NOTFOUND CURSORNAME%ISOPEN CURSORNAME%ROWCOUNT

CURSORNAME%FOUND 表示指定的遊標是否至少有一條記錄被fetch了。

當一個顯示遊標被Open以後,如果還一次都沒被Fetch,那麼CURSORNAME%FOUND的值就是null,當這個顯示遊標被Fetch後,CURSORNAME%FOUND的值為true,直到全部Fetch完畢。而全部Fetch完畢後,如果在執行一次Fetch操作,Oracle不會報錯,但是CURSORNAME%FOUND的值變成了false。

CURSORNAME%ISOPEN 表示指定的顯示遊標是否被OPen了。主要用於異常流中。

CURSORNAME%NOTFOUND表示指定的遊標是否已經Fetch完畢了。

CURSORNAME%NOTFOUND在語義上和CURSORNAME%FOUND完全相反。 當一個顯示遊標被OPEN以後,如果還一次都沒用Fetch,那麼CURSORNAME%NOTFOUND的值是NULL。當這個顯示遊標Fetch以後,CURSORNAME%NOTFOUND的值為False,知道全部Fetch完畢。全部Fetch完畢後,如果這個時候再進行Fetch,那麼CURSORNAME%NOTFOUND的值為TRUE。

CURSORNAME%ROWCOUNT 表示指定的顯示遊標迄今為止一共Fetch了多少行記錄。

PLSQL程式碼 顯示遊標的標準用法:

create or replace procedure  P_DEMO_EXPLICIT_CURSOR_STD  is

  cursor cl is select * from emp where rownum < 12;
  emp_rec emp%rowtype;

begin
  open c1;
  fetch c1 into emp_rec;
  while (cl%found) loop
    dbms_output.put_line('name='||emp_rec.enmae||',salary='||emp.rec.sal);

    fetch cl into emp_rec;
    end loop;
    close c1;
   exception
      when others then
        --o_parm:='E'||sqlcode||sqlerrm;
        rollback;
        --寫日誌
        return;

  end P_DEMO_EXPLICIT_CURSOR_STD;

    以下幾點需要注意: 1 顯示遊標的標準用法是先OPEN,再Fetch,然後用一個while迴圈處理資料,最後是close。 2 在上述顯示遊標的標準用法的while迴圈內部處理晚一條記錄後,一定要記得執行fetch操作以跳到下一條記錄,否則就是死迴圈。