获取游标属性值的语法是 cursor_name%attribute,如:c1%NOTFOUND。游标属性类型如下:

  • %FOUND 布尔型属性,当最近一次读游标返回记录,则值为 TRUE。

  • %NOTFOUND 布尔型属性,与 %FOUND 相反。

  • %ISOPEN 布尔型属性,当游标已打开时返回 TRUE。

  • %ROWCOUNT 数字型属性,返回已从游标中读取的记录数。

常用的游标属性及其返回值

属性名

声明的游标的值

隐式游标的值

%FOUND

如果游标是打开状态,但是没有 FETCH 操作,则返回 NULL。

如果最近一次 FETCH 操作返回了一行记录,则返回 TRUE 。

如果最近一次 FETCH 操作没有返回记录,则返回 FALSE 。

如果没有 DML 或 SELECT INTO 语句运行,则返回 NULL 。

如果最近运行的 DML 或 SELECT INTO 语句返回一行记录,则返回 TRUE 。

如果最近运行的 DML 或 SELECT INTO 语句没有返回记录, 则返回 FALSE 。

%NOTFOUND

如果游标是打开状态,但是没有FETCH操作,则返回 NULL。

如果最近一次 FETCH 操作返回了一行记录,则返回 FALSE。

如果最近一次 FETCH 操作没有返回记录,则返回 TRUE。

如果没有 DML 或 SELECT INTO 语句运行,则返回 NULL 。

如果最近运行的 DML 或 SELECT INTO 语句返回一行记录,则返回 FALSE。

如果最近运行的 DML 或 SELECT INTO 语句没有返回记录, 则返回 TRUE。

%ROWCOUNT

如果游标是打开状态,会返回一个大于或等于 0 的数字。

如果没有 DML 或 SELECT INTO 语句运行,则返回 NULL ;否则,返回一个大于或等于 0的数字。

%ISOPEN

如果游标是打开状态,返回 TRUE ;否则,返回 FALSE 。

总是 FALSE 。

示例

示例:简单游标获取数据。

  1. obclient> DECLARE
  2. -> CURSOR c_emp IS SELECT first_name, salary
  3. -> FROM employees where rownum<5;
  4. -> v_ename employees.first_name%TYPE;
  5. -> v_sal employees.salary%TYPE;
  6. -> BEGIN
  7. -> OPEN c_emp;
  8. -> FETCH c_emp INTO v_ename, v_sal;
  9. -> WHILE c_emp%FOUND LOOP
  10. -> DBMS_OUTPUT.PUT_LINE(v_ename||'''s salary is '||to_char(v_sal) );
  11. -> FETCH c_emp INTO v_ename, v_sal;
  12. -> END LOOP;
  13. -> CLOSE c_emp;
  14. -> END;
  15. -> /
  16. Query OK, 0 rows affected (0.05 sec)
  17. Neena's salary is 17000
  18. Lex's salary is 17000
  19. Alexander's salary is 9000
  20. Bruce's salary is 6000

示例:使用参数传递。

  1. obclient> DECLARE
  2. -> CURSOR c_emp (in_job_id varchar default 'AC_MGR' ) IS
  3. -> SELECT first_name, salary
  4. -> FROM employees where job_id = in_job_id;
  5. -> v_jobid employees.job_id%TYPE;
  6. -> v_emp_name employees.first_name%TYPE;
  7. -> v_sal employees.salary%TYPE;
  8. -> BEGIN
  9. -> v_jobid := 'IT_PROG';
  10. -> OPEN c_emp(in_job_id => v_jobid);
  11. -> LOOP
  12. -> FETCH c_emp INTO v_emp_name, v_sal;
  13. -> EXIT WHEN c_emp%NOTFOUND;
  14. -> DBMS_OUTPUT.PUT_LINE('DEPT '||v_jobid||': '||v_emp_name||'''s salary is '||to_char(v_sal) );
  15. -> END LOOP;
  16. -> CLOSE c_emp;
  17. -> END;
  18. -> /
  19. Query OK, 0 rows affected (0.05 sec)
  20. DEPT IT_PROG: Alexander's salary is 9000
  21. DEPT IT_PROG: Bruce's salary is 6000
  22. DEPT IT_PROG: David's salary is 4800
  23. DEPT IT_PROG: Valli's salary is 4800
  24. DEPT IT_PROG: Diana's salary is 4200

NO_DATA_FOUND 与 %NOTFOUND 的区别

不同点

NO_DATA_FOUND

%NOTFOUND

定义不同

NO_DATA_FOUND 是异常定义

%NOTFOUND 是游标属性

触发条件不同

SELECT … INTO 语句会触发 NO_DATA_FOUND

  • 当一个显式游标的 WHERE 子句未找到时会触发 %NOTFOUND

  • 当 UPDATE 或 DELETE 语句的 WHERE 子句未找到时,会触发 SQL%NOTFOUND

  • 在提取循环中要用 %NOTFOUND%FOUND 来确定循环的退出条件。