在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;