1. 程式人生 > >PL/SQL -- 隱式遊標 SQL FOUND

PL/SQL -- 隱式遊標 SQL FOUND

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

               

--===============================

-- PL/SQL -->隱式遊標(SQL%FOUND)

--===============================

 

    PL/SQL中,遊標的使用分為兩種,一種是顯示遊標,一種是隱式遊標,顯示遊標的使用需要事先使用declare來進行宣告,其過程包括

宣告遊標,開啟遊標,從遊標提取資料,關閉遊標。該方式多用於處理select語句返回的多行資料的情形。而隱式遊標則由則由系統自動定義

,當DML被使用時,Oracle為每一個不屬於顯示遊標的DML語句都建立一個隱式遊標,其宣告、開啟、關閉都是系統自動進行。多用於配合DML

返回單行資料的處理。

    有關顯示遊標的使用,請參考:PL/SQL -->

   

一、隱式遊標的定義及其屬性

    定義

        隱式遊標則由則由系統自動定義,非顯示定義遊標的DML語句即被賦予隱式遊標屬性。其過程由oracle控制,完全自動化。隱式遊標

        的名稱是SQL,不能對SQL遊標顯式地執行OPEN,FETCH,CLOSE語句。

    屬性

       

類似於顯示遊標,隱式遊標同樣具有四種屬性,只不過隱式遊標以SQL%開頭,而顯示遊標以Cursor_name%開頭

        通過SQL%總是隻能訪問前一個DML操作或單行SELECT操作的遊標屬性,用於判斷DML執行的狀態和結果,進而控制程式的流程

       

        SQL%ISOPEN   

            遊標是否開啟。當執行select into ,insert update,delete時,Oracle會隱含地開啟遊標,且在該語句執行完畢或隱含地關閉

            遊標,因為是隱式遊標,故SQL%ISOPEN總是false  

           

        SQL%FOUND      

            判斷SQL語句是否成功執行。當有作用行時則成功執行為true,否則為false

                   

        SQL%NOTFOUND   

            判斷SQL語句是否成功執行。當有作用行時否其值為false,否則其值為true

           

        SQL%ROWCOUNT  

            在執行任何DML語句之前,SQL%ROWCOUNT的值都是NULL,對於SELECT INTO語句,如果執行成功,SQL%ROWCOUNT的值為,如果沒有

            成功,SQL%ROWCOUNT的值為,同時產生一個異常NO_DATA_FOUND

       

二、演示

    1.SQL%FOUND的使用

        DECLARE

          v_empno emp.empno%TYPE:=&no;

        BEGIN

          UPDATE emp SET sal=sal+200     --根據給定的empno,更新一條記錄

          WHERE empno=v_empno;

          IF SQL%FOUND THEN              --使用SQL遊標屬性SQL%FOUND作為判斷條件

            COMMIT;

            DBMS_OUTPUT.PUT_LINE('SQL code is executed successful');

          ELSE

            DBMS_OUTPUT.PUT_LINE('The Employee is not exist');

            ROLLBACK;

          END IF;

        END;

 

        Enter value for no: 7788

        old   2:   v_empno emp.empno%TYPE:=&no;

        new   2:   v_empno emp.empno%TYPE:=7788;

        SQL code is executed successful

 

        PL/SQL procedure successfully completed

   

    2.SQL遊標的綜合應用(根據SQL遊標的不同屬性返回不同的結果)

        DECLARE

          v_dept emp.deptno%TYPE := &no;

 

        BEGIN

 

          IF SQL%ROWCOUNT >= 0 THEN  --判斷更新前SQL%ROWCOUNT的屬性

            DBMS_OUTPUT.PUT_LINE('SQL%ROWCOUNT value is ' || SQL%ROWCOUNT ||

                                 'before updated');

          ELSE

            DBMS_OUTPUT.PUT_LINE('SQL%ROWCOUNT value is NULL before updated');

          END IF;

 

          UPDATE emp SET sal = sal + 200 WHERE deptno = v_dept;

 

          IF SQL%FOUND THEN    --判斷SQL%FOUND的屬性

            DBMS_OUTPUT.PUT_LINE('SQL code is executed successful');

            DBMS_OUTPUT.PUT_LINE('SQL%Found is TRUE');

          ELSE

            DBMS_OUTPUT.PUT_LINE('No such department');

            DBMS_OUTPUT.PUT_LINE('SQL%Found is FALSE');

          END IF;

 

          IF SQL%NOTFOUND THEN    --判斷SQL%NOTFOUND的屬性

            DBMS_OUTPUT.PUT_LINE('SQL%NotFound is TRUE');

          ELSE

            DBMS_OUTPUT.PUT_LINE('SQL%NotFound is FALSE');

          END IF;

 

          IF SQL%ISOPEN THEN    --判斷SQL%ISOPEN的屬性

            DBMS_OUTPUT.PUT_LINE('SQL%ISOPEN is TRUE');

          ELSE

            DBMS_OUTPUT.PUT_LINE('SQL%ISOPEN is FALSE');

          END IF;

 

          DBMS_OUTPUT.PUT_LINE('The rows updated is :' || SQL%ROWCOUNT ||

                               ' rows by SQL Cursor'); --判斷SQL%ROWCOUNT的屬性

        END;

       

        Enter value for no: 10   --下面是成功更新後的結果

        SQL%ROWCOUNT value is NULL before updated

        SQL code is executed successful

        SQL%Found is TRUE

        SQL%NotFound is FALSE

        SQL%ISOPEN is FALSE

        The rows updated is :3 rows by SQL Cursor

       

        Enter value for no: 80   --下面是未成功更新後的結果

        SQL%ROWCOUNT value is NULL before updated

        No such department

        SQL%Found is FALSE

        SQL%NotFound is TRUE

        SQL%ISOPEN is FALSE

        The rows updated is :0 rows by SQL Cursor  

       

    3.SELECT INTO時,隱式遊標的使用

        SELECT INTO用於將單行結果集放置到變數之中。

        SELECT INTO處理的結果包括兩種種情況

            查詢結果返回單行,SELECT INTO被成功執行

            查詢結果沒有返回行,PL/SQL將丟擲no_data_found異常

            查詢結果返回多行,PL/SQL將丟擲too_many_rows 異常

        對於上述兩種異常發生時,類似於普通異常處理,程式控制權轉移到異常處理部分(如沒有異常處理則程式中斷)。對於異常被激後發

        SQL遊標的四個屬性在此將不可使用,如下面的例子:

            DECLARE

              v_ename emp.ename%TYPE;

             

            BEGIN

              SELECT ename INTO v_ename FROM emp WHERE empno=&no;

              IF  SQL%ROWCOUNT=0 OR SQL%NOTFOUND THEN

                DBMS_OUTPUT.PUT_LINE('The record '||&no||' is not exist!');

              ELSE

                DBMS_OUTPUT.PUT_LINE('The name for record '||&no||' is '||v_ename );

              END IF;

 

            EXCEPTION 

              WHEN NO_DATA_FOUND THEN

                DBMS_OUTPUT.PUT_LINE('No data found for '||&no);

              

            END;       

           

            Enter value for no:70

            No data found for 70

           

            Enter value for no:7788

            The name for record 7788 is SCOTT

           

        從上面的演示中可以看到,當select into沒有返回行時,IF  SQL%ROWCOUNT=0 OR SQL%NOTFOUND THEN 語句並沒有被執行。

        使用下面改進過的程式碼來執行,即可以將SQL遊標屬性判斷放置到EXCEPTION部分

            DECLARE

              v_ename emp.ename%TYPE;

             

            BEGIN

              SELECT ename INTO v_ename FROM emp WHERE empno=&no;

              IF SQL%NOTFOUND THEN

                DBMS_OUTPUT.PUT_LINE('The record '||&no||' is not exist!');

              ELSE

                DBMS_OUTPUT.PUT_LINE('The name for record '||&no||' is '||v_ename );

              END IF;

 

            EXCEPTION 

              WHEN NO_DATA_FOUND THEN

                IF SQL%NOTFOUND THEN

                  DBMS_OUTPUT.PUT_LINE('The record '||&no||' is not exist!');

                  DBMS_OUTPUT.PUT_LINE('No data found for '||&no);

                ELSE

                  DBMS_OUTPUT.PUT_LINE('The name for record '||&no||' is '||v_ename );

                END IF;

              

            END;

           

            Enter value for no:80

            The record 80 is not exist!

            No data found for 80

           

        更多關於隱式遊標的探討,請參考:IMPLICIT CURSOR ATTRIBUTE SQL%NOTFOUND NOT WORKING 

               

三、更多參考

有關SQL請參考

        SQL 基礎--> 子查詢

        SQL 基礎-->多表查詢

SQL基礎-->分組與分組函式

SQL 基礎-->常用函式

SQL 基礎--> ROLLUP與CUBE運算子實現資料彙總

SQL基礎-->層次化查詢(START BY ... CONNECT BY PRIOR)

 

    有關PL/SQL請參考

        PL/SQL --> 語言基礎

PL/SQL --> 流程控制

PL/SQL --> 儲存過程

PL/SQL --> 函式

PL/SQL --> 遊標

PL/SQL -->隱式遊標(SQL%FOUND)

PL/SQL --> 異常處理(Exception)

PL/SQL --> PL/SQL記錄

PL/SQL --> 包的建立與管理

PL/SQL --> 包過載、初始化

PL/SQL --> DBMS_DDL包的使用

PL/SQL --> DML 觸發器

PL/SQL --> INSTEAD OF 觸發器

 

 

       

           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述