PL/SQL -->隐式游标(SQL%FOUND)

系统 2098 0

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

-- 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 触发器

 

 

       

PL/SQL -->隐式游标(SQL%FOUND)


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论