ITPub博客

首页 > 数据库 > Oracle > PLSQL Language Referenc-PL/SQL静态SQL-静态SQL的描述-光标-隐式光标

PLSQL Language Referenc-PL/SQL静态SQL-静态SQL的描述-光标-隐式光标

原创 Oracle 作者: luisedalian 时间:2014-03-14 07:54:36 0 删除 编辑

光标

光标是私有SQL区域的指针,该区域存储着关于处理特定SELECTDML语句的信息。

本单描述的光标是会话光标。会话光标存在于会话内存中直到会话结束。会话光标不同于在PGA的私有SQL区域的光标。

PL/SQL程序构造和管理的会话光标是隐式光标;而由你构造和管理的会话光标为显式光标

可以从它的属性获得会话光标的信息。(可以在过程语句中引用,不能在SQL语句中引用)

可以通过查询动态性能视图v$open_cursor,来列出每个用户会话当前打开和解析的会话光标。

注意:通常PL/SQL会在它第1次打开显式光标时来解析它,在SQL语句第1次执行时来解析它(会创建隐式光标)。所有被解析的SQL语句都被缓存。只有当它被新的SQL语句变得超期后,才会被重新解析。尽管你在再次打开显式光标时必须先关闭它,PL/SQL不需要重新解析关联的查询。如果你在关闭之后立即重新打开了一个显式光标,PL/SQL不需要重新解析关联的查询。

隐式光标

隐式光标是由PL/SQL构造和管理的会话光标。PL/SQL会在每次运行SELECTDML语句时打开隐式光标,你不能控制隐式光标,但可以从它的属性获得信息。

隐式光标的属性值的语法是SQLattribute,所以隐式光标也称为SQL光标SQLattribute总是指向最后被执行的SELECTDML语句,如果没有这样的语句已经运行,则SQLattribute的值为NULL

隐式光标在与它关联的语句运行之后就关闭了,但它的属性值保留可用,直到另一个SELECTDML语句运行。

最近运行的SELECTDML语句可能在不同的范围之中。为了保存属性值以备后用,可以立即将它存储在本地变量之中。否则其它的操作,例如子程序调用,可能在测试它之前,已经改变了属性的值。

1SQL%ISOPEN

始终返回false,因为隐式光标在它关联的语句运行完之后永远是关闭的。

2SQL%FOUND

n  NULL-如果没有SELECTDML语句运行

n  TRUE-如果SELECTDML语句返回或影响了一行或多行

n  FALSE-其它

DROP TABLE dept_temp;

CREATE TABLE dept_temp AS

    SELECT * FROM departments;

 

CREATE OR REPLACE PROCEDURE p (dept_no NUMBER) AUTHID DEFINER AS

BEGIN

    DELETE FROM dept_temp

    WHERE department_id = dept_no;

 

    IF SQL%FOUND THEN

        DBMS_OUTPUT.PUT_LINE ('成功删除的部门编号:' || dept_no);

    ELSE

        DBMS_OUTPUT.PUT_LINE ('没有该部门:' || dept_no);

    END IF;

END;

 

BEGIN

    p(270);

    p(400);

END;

3SQL%NOTFOUND

SQL%FOUND返回的值相反。

n  NULL-如果没有SELECTDML语句运行

n  FALSE-如果SELECTDML语句返回或影响了一行或多行

n  FALSE-其它

该属性对于PL/SQL中的SELECT INTO语句没用,因为:

n  如果SELECT INTO没有返回行,则会在你检查SQL%NOTFOUND的值之前,引发NO_DATA_FOUND异常。

n  调用SQL集合函数的SELECT INTO语句总会返回值(可能为NULL),在这样的语句之后SQL%NOTFOUND的值始终为FALSE,所以也没必要检查它的值了。

4SQL%ROWCOUNT

n  NULL-如果没有SELECTDML语句运行

n  如果SELECTDML语句返回或影响了的行数

DROP TABLE employees_temp;

CREATE TABLE employees_temp AS

    SELECT * FROM employees;

 

DECLARE

    mgr_no NUMBER(6) := 122;

BEGIN

    DELETE FROM employees_temp WHERE manager_id = mgr_no;

    DBMS_OUTPUT.PUT_LINE('删除的员工数量: ' || TO_CHAR(SQL%ROWCOUNT));

END;

 

如果没有带BULK COLLECT子句SELECT INTO语句返回多条记录,PL/SQL会引发TOO_MANY_ROWS异常,此时SQL%ROWCOUNT的值为1,而不是实际查询的行。

SQL%ROWCOUNT的值与事务的状态无关,因此:

n  当事务回滚到一个保存点,SQL%ROWCOUNT的值并不恢复到保存点之前的值。

n  当自治事务结束时,SQL%ROWCOUNT的值并不恢复到父事务中的原始值。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/17013648/viewspace-1118614/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2012-02-06

  • 博文量
    1986
  • 访问量
    5677586