PLSQL基礎(三)遊標

來源:互聯網
上載者:User

遊標有兩種:

顯示遊標,隱式遊標

 

顯示遊標是用CURSOR...IS命令定義的遊標,它可以對查詢語句(SELECT)返回的多條記錄進行處理,而隱式遊標是在執行插入(INSERT),刪除(DELETE),修改(UPDATE)和返回單條記錄的查詢(SELECT)語句時由PLSQL自動定義的。

 

顯示遊標的操作

1)開啟遊標    2)推進遊標     3)關閉遊標

 

 

聲明遊標:

DECLARE

    v_auths auths%ROWTYPE;

    v_code auths.author_code%TYPE;

    CURSOR c_auths IS

     SELECT * FROM auths WHERE author_code = v_code;

 

開啟遊標:

v_code = 'A00001';

OPEN c_auths;

 

聲明遊標

DECLARE

    CURSOR c_Auths(P_code auths.author_code%TYPE) IS

    SELECT * FROM auths WHERE author_code = P_code;

開啟遊標

OPEN c_Auths('A00001');

 

當開啟顯示遊標後,就可以使用FETCH語句來推進遊標,返回查詢結果中的一行。沒執行完一條FETCH語句後,顯示遊標會自動指向查詢結果集的下一行。

FETCH c_Auths INTO c_Auths;

 

當整個結果集都檢索完以後,應當關閉遊標,關閉遊標用來通知PLSQL遊標操作已經結束,並且釋放遊標所佔用的資源.

CLOSE cursor_name;

 

 

遊標的屬性

遊標有四個屬性 %FOUND,%NOTFOUND,%ISOPEN,%ROWCOUNT

 

顯式遊標的推薦迴圈

DECLARE

    v_Salary  Auths.salary%TYPE;

    v_Code    Auths.author_code%TYPE;

    CURSOR c_salary IS

    SELECT salary,author_code FROM auths WHERE author_code <= 'A00006';

BEGIN

     OPEN c_salary;

    LOOP

         FETCH c_salary INTO v_Salary,v_Code;

         EXIT WHEN c_salary%NOTFOUNT;

         IF v_salary <= 2000 THEN

              UPDATE auths SET salary = salary + 50 WHERE author_code = v_Code;

         END IF;

     END LOOP;

 

     CLOSE c_salary;

   COMMIT;

END;

 

無論是使用LOOP...END LOOP語句還是使用WHILE...LOOP語句來完成遊標的推進迴圈,都必須使用OPEN,FETCH,CLOSE語句來控制遊標的開啟,推進和關閉,PLSQL還提供了一種簡單類型的迴圈,可以自動控制遊標的開啟,推進和關閉,這叫做遊標的FOR迴圈.

DECLARE

    CURSOR c_salary IS

    SELECT salary FROM auths WHERE author_code <= 'A00006';

BEGIN

--開始遊標FOR迴圈,隱含地開啟c_salary遊標

    FOR v_salary IN c_calary LOOP

          IF v_salary.salary <= 200 THEN

               UPDATE auths SET salary = salary + 50 WHERE salary = v_salary.salary;

          END IF;

    END LOOP;

    COMMIT;

END;

 

上例中v_salary沒有在塊的定義部分聲明,該變數被PLSQL編譯器隱含的聲明了,該變數的類型為c_salary%ROWTYPE,其範圍只在迴圈內部。

 

 

 

隱式遊標

顯示遊標僅僅是用來控制返回多行的SELECT語句,而隱式遊標是指向處理所有的SQL語句的環境地區的指標,隱式遊標也叫SQL遊標,與顯示遊標不同的是,SQL遊標不能通過專門的命令開啟或關閉,PLSQL隱式的開啟SQL遊標,並在它內部處理SQL語句,然後關閉它。

SQL遊標用來處理INSERT,UPDATE,DELETE以及返回一行的SELECT ...INTO語句。一個SQL遊標不管是開啟還是關閉,OPEN,FETCH,CLOSE命令都不能操作它。

SQL遊標與顯示遊標類似,也有%FOUND,%NOTFOUND,%ISOPEN,%ROWTYPE屬性,SQL遊標的屬性通常是返回執行INSERT,DELETE,UPDATE或SELECT...INTO語句時的資訊,當開啟SQL遊標之前,SQL遊標的屬性都是NULL.

%FOUND

當使用INSERT,DELETE或者UPDATE語句處理一行或多行,或執行SELECT INTO語句返回一行時,%FOUND屬性返回TRUE,否則返回FALSE.

注意:如果執行SELECT INTO語句時返回多行,則會產生TOO_MANEY_ROWS異常,並將控制權轉移到異常處理部分,%FOUND屬性並不返回TRUE.如果執行SELECT INTO語句時返回0行,會產生NO_DATE_FOUND異常,%FOUND屬性並不返回FALSE.

 

%NOTFOUND

%NOTFOUND恰與%FOUND屬性相反,當使用INSERT,DELETE或者UPDATE語句處理的函數為0時,%NOTFOUND屬性返回TRUE,否則返回FALSE.

 

%ISOPEN

因為在執行了DML語句後,Oracle會自動關閉SQL遊標,所以%ISOPEN總會FALSE.

 

%ROWCOUNT

該屬性返回執行INSERT,DELETE或UPDATE語句返回的行數,或返回執行SELECT INTO語句時查詢的行數,如果INSERT,DELETE,UPDATE或SELECT INTO語句返回的行數為0,則%ROWTYPE屬性返回0.

BEGIN  

      UPDATE auths SET entry_date_time = SYSDATE WHERE author_code = 'A00007';

     --如果UPDATE語句中修改的行不存在(SQL%NOTFOUND返回TURE)

 IF SQL%NOTFOUND THEN

      INSERT INTO auths values(......)......

END IF;

END;

我們使用SQL%ROWCOUNT完成與上例相同的功能。

BEGIN

    UPDATE auths SET entry_date_time = SYSDATE WHERE author_code = 'A00007';

     IF SQL%ROWCOUNT = 0 THEN

         INSERT INTO ......

    END IF;

END;

 

 

 

遊標變數

到目前為止前面所有顯示遊標的例子都是靜態資料指標----即遊標與一個SQL語句關聯,並且該SQL語句在編譯時間已經確定,而遊標變數是一個參考型別(REF)的變數,當程式運行時使用遊標變數可以指定不同的查詢,所以遊標變數的使用比靜態資料指標更靈活。

我們可以使用一個沒有指定結果集類型的遊標變數來指定多個不同類型的查詢.

DECLARE

--定義遊標變數類型t_CurRef,該變數類型沒有指定結果集類型,所以該遊標變數類型的變數可以返回不同的PLSQL記錄類型

        TYPE t_CurRef IS REF COUSOR

--聲明一個遊標變數類型的變數

          c_CursorRef t_CurRef;

--定義PLSQL記錄類型

         TPYE t_AuthorRec IS RECORD

        (

                AuthorCode auths.author_code%TYPE;

                Name auths.name%TYPE

        );

       

        TYPE t_ArticleRec IS RECODE

         (

                 AuthorCode article.author_code%TYPE

                 Title     article.Title%TYPE

           );

  --聲明兩個記錄類型變數

   v_Author t_AuthorRec;

   v_Ariticle  t_ArticleRec;

BEGIN

--開啟遊標變數c_CursorRef,返回t_AuthorRec類型的記錄

    OPEN  c_CursorRef FOR

     SELECT author_code,name FROM auths;

    

     FECTCH c_CursorRef INTO v_Author;

     WHILE c_CursorRef%FOUND LOOP

           ...

           FETCH c_CursorRef INTO v_Author;

     END LOOP;

   

     CLOSE c_CursorRef;

 

     OPEN c_CursorRef FOR

     SELECT  author_code,title FROM ariticle

      FETCH c_CursorRef INTO v_Article;

     WHILE c_CursorRef%FOUND LOOP

                   ...

            FETCH c_CursorRef INTO v_Article;

    END LOOP;

   

    CLOSE c_CursorRef;

END;

 

 

注意,在上例中,第一次關閉遊標變數是可以省略的,因為在第二次開啟遊標變數是,就將第一次的查詢丟失掉了.

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.