数据库在进行SQL语句执行的时候都必须要利用游标了,无论是显示的或隐示的游标。处理游标需要经历以下步骤。
打开游标 ----- 系统会在与这个会话相关的服务器进程的服务器端私有内存中为这个游标分配一个内存结构,也就是用户全局区(User Global Area, UGA).注意,SQL语句与游标还没有关联。
解析游标 ----- 有一条SQL语句与这个游标关联。解析后内容(包含执行计划)会被加载到共享池中,明确地讲,是加载到库缓存(library cache)中。UGA中的结构会被更新,以保存指向这个共享游标在库缓存中的位置。
定义输出变量 ------ 如果SQL语句返回数据,必须先定义结束数据的变量。
绑定输入变量 ------- 如果SQL语句使用了绑定变量,必须提供它们的值。绑定的过程是不做什么检查。
执行游标 -------- 执行这个SQL语句。数据库引擎并非是在这一步做重要的事情。事实上,对于很多类型的查询语句来讲,真正的处理过程通常会被推迟到获取(fetch)数据阶段。
获取游标 ----- 如果SQL语句返回数据,这一步会接受这些数据。特别是在查询语句中,大部分的处理工作都是在这一步进行的。
关闭游标-----释放UGA中与这个游标有关的资源,从而这些资源可供其它游标使用。在库缓存中的共享游标不会被清除。它会继续保留在库缓存中,以期被重新使用.
用下面PL/SQL代码示例SQL语句的处理步骤:
DECLARE l_ename emp.ename%TYPE := 'SCOTT'; l_empno emp.empno%TYPE; l_cursor INTEGER; l_retval INTEGER; BEGIN l_cursor := dbms_sql.open_cursor; --打开游标 dbms_sql.parse(l_cursor, 'SELECT empno FROM emp WHERE ename = :ename', 1); --解析游标 dbms_sql.define_column(l_cursor, 1, l_empno); --定义输出变量 dbms_sql.bind_variable(l_cursor, ':ename', l_ename); --绑定输入变量 l_retval := dbms_sql.execute(l_cursor); --执行游标 IF dbms_sql.fetch_rows(l_cursor) > 0 --获取数据 THEN dbms_sql.column_value(l_cursor, 1, l_empno); dbms_output.put_line(l_empno); END IF; dbms_sql.close_cursor(l_cursor); --关闭游标 END;
隐示游标例子:
DECLARE l_ename emp.ename%TYPE := 'SCOTT'; l_empno emp.empno%TYPE; BEGIN SELECT empno INTO l_empno FROM emp WHERE ename = l_ename; dbms_output.put_line(l_empno); END;
解析的全过程
1.包含VPD的约束条件
2.语法、语义以及访问权限检查
3.将父游标保存到库缓存
4.逻辑优化
5.物理优化
6.将子游标保存到库缓存