PL/SQL -->隐式游标(SQL%FOUND)
--===============================
-- 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 基础--> ROLLUP与CUBE运算符实现数据汇总
SQL基础-->层次化查询(START BY ... CONNECT BY PRIOR)
有关PL/SQL请参考
PL/SQL -->隐式游标(SQL%FOUND)的更多相关文章
- PL/SQL — 隐式游标
一.隐式游标的定义及其属性 定义 隐式游标由系统自动定义,非显示定义游标的DML语句即被赋予隐式游标属性.其过程由oracle控制,完全自动化.隐式游标的名称是SQL,不能对SQL游标显式地执行OPE ...
- 【Oracle】PL/SQL 显式游标、隐式游标、动态游标
在PL/SQL块中执行SELECT.INSERT.DELETE和UPDATE语句时,Oracle会在内存中为其分配上下文区(Context Area),即缓冲区.游标是指向该区的一个指针,或是命名一个 ...
- Oracle pl/sql 显示游标和隐式游标
显示游标 一.定义语法: CURSOR <游标名> IS <SELECT 语句> [FOR UPDATE | FOR UPDATE ...
- PL/SQL — 显式游标
一.游标的相关概念及特性 1.定义 通过游标方式定位到结果集中某个特定的行,然后根据业务需求对该行进行相应特定的操作. 2.分类 显示游标: 用户自定义游标,用于处理select语句返回的多行数据. ...
- oracle的隐式游标
游标的概念: 游标是SQL的一个内存工作区,由系统或用户以变量的形式定义.游标的作用就是用于临时存储从数据库中提取的数据块.在某些情况下,需要把数据从存放在磁盘的表中调到计算机内存中进行处理, ...
- Oracle异常处理内容,隐式游标
异常处理 create or replace procedure pr_test3(v_bh in varchar2,v_xx out t_hq_ryxx%rowtype) is begin sele ...
- Oracle游标cursor1基础和隐式游标
--指向表行的指针,一次一行,一般向前移动 Resultset --游标永远代代表的是一行数据. /* 使用步骤 第一步:声明游标,就像是声明一个变量样. 游标的关键字就是cursor. Declar ...
- ORACLE的显式游标与隐式游标
1)查询返回单行记录时→隐式游标: 2)查询返回多行记录并逐行进行处理时→显式游标 显式游标例子: DECLARE CURSOR CUR_EMP IS SELECT * FROM EMP; ROW_E ...
- Oracle 隐式游标 存储过程
--隐式游标 注意变量赋值用(:=) 连接符用(||)而不是加号(+) DECLARE v_pk T_PLAT_KEYWORD.ID%TYPE; --主键 v_amount_message T_PLA ...
随机推荐
- BZOJ 3158 千钧一发 最小割
分析: 偶数对满足条件2,所有奇数对满足条件1. 如果你能一眼看出这个规律,这道题就完成了一半. 我们只需要将数分为两类,a值为奇数,就从S向这个点连容量为b值的边,a值为偶数,就从这个点向T连容量为 ...
- 源码学习-String类
最近在扫描CodeDex时报了一个不能使用String.intern()的字符串来做锁对象的告警,对这个问题有疑问查了些资料,顺便学习一下String类的源码. 1.类定义 String 被final ...
- node函数assert()详解
assert.ok() 的别名. const assert = require('assert'); assert(true); // OK assert(1); // OK assert(false ...
- PHP:验证手机号码合法性
文章来源:http://www.cnblogs.com/hello-tl/p/7592333.html /** * [verifyPhone description] 效验手机号码合法性 * @par ...
- Spider-scrapy断点续爬
scrapy的每一个爬虫,暂停时可以记录暂停状态以及爬取了哪些url,重启时可以从暂停状态开始爬取过的URL不在爬取 实现暂停与重启记录状态 方法一: 1.首先cd进入到scrapy项目里(当然你也可 ...
- PS注意点
2.颜色 设计师应该具备审美能力. 3.实验 不断的练习会让你学习到更多的东西,请不要给自己太多压力,你的付出不会仅仅只让你原地踏步,要坚持. 填充和不透明的掌握. 还有流量的使用. 填充是一 ...
- POJ 2479 两段连续最大和
题目大意: 在一组数中,找到连续的两段 , 是这两段相加和达到最大 这里利用dp[2][N]的数组保存所有的状态 dp[0][i]表示取到第i个数时只取了一段的最大和,第i个数是一定要被取到的 dp[ ...
- 洛谷——P1164 小A点菜
P1164 小A点菜 题目背景 uim神犇拿到了uoi的ra(镭牌)后,立刻拉着基友小A到了一家……餐馆,很低端的那种. uim指着墙上的价目表(太低级了没有菜单),说:“随便点”. 题目描述 不过u ...
- ubuntu忘记root密码的解决办法
ubuntu忘记密码,不需要重装系统即可重新设置root密码,以下是步骤: 1)在系统一启动时,按ESC键,目的是为了出现选单页面 2) 当看到选单页面时,此时按下[e] 这个键,此时会进入grub ...
- hdu3756(三分)
题意:三维坐标轴,有以原点为圆心,底面在xoy平面上,顶点在z轴上的圆锥,问圆锥的最小体积为多少才能完全覆盖空间里的所有点(n<=10000) 分析: 很容易想到转成二维问题,将其投影到xoz平 ...