【翻译】Oracle游标详细说明

这篇文章是选取官方文档的部分章节翻译过来的,去除了原文中的例子,并在结尾补充了几个例子。有兴趣的朋友可以点击文章末尾的连接去阅读官方文档。

一、游标的定义

游标是指向专用SQL区域的指针,该区域存储有关处理特定SELECT或DML语句的信息。本章解释的游标是会话游标。会话游标存在于会话中直到会话结束。由PL/SQL创建和管理的游标称为隐式游标,由用户创建和管理的游标称为显式游标。你可以通过游标的属性获取任意会话游标的相关信息。通过查询动态性能视图V$OPEN_CURSOR,可以列出当前已经打开和解析的游标。

二、隐式游标

每次执行select 或DML操作时,都会生成隐式游标。用户不能控制隐式游标,但可以通过游标的属性获取游标的信息。

隐式游标属性的语法是SQLattribute(因此隐式游标也通常叫做SQL游标)。SQLattribute总是指向最近运行的select或DML语句。如果最近没有运行这样的语句,则属性返回NULL。

当语句运行结束时,隐式游标关闭,但是它的属性会被保留到另一条select或DML语句执行。最近的语句运行的结果可能属于不同的值,如果要保留属性值供以后使用,可以将其保存在本地变量中。另外,其他的操作,如子程序的调用,可能在你测试之前改变属性值。

隐式游标的属性有以下几种:

属性 说明 备注
SQL%ISOPEN FALSE 隐式游标总是在与其相关联的语句结束之后关闭,因此总是返回FALSE
SQL%FOUND NULL 没有执行select或DML操作
TRUE select语句返回一行或多行或者DML操作影响了一行或者多行
FALSE 其他情况
SQL%NOTFOUND NULL 没有执行select或DML操作 在select into中无用,没有值时会报no_data_found的错误;有值时验证已经没有意义。
TRUE select语句返回一行或多行或者DML操作影响了一行或者多行
FALSE 其他情况
SQL%ROWCOUNT NULL 没有执行select或DML操作 select into中返回多行时会报too_many_data的错误,并且返回1.
数值 返回的数值表示select返回了多少行以及DML操作影响了多少行
SQL%BULK_ROWCOUNT 数值 FORALL语句完成后,从隐式游标属性SQL%BULK_ROWCOUNT获取每个DML语句影响的行数。
SQL%BULK_EXCEPTIONS FORALL语句完成后,如果执行期间有异常生成,会将异常数据保存在SQL%BULK_EXCEPTIONS中。

三、显式游标

显式游标由用户创建并管理。用户在使用显式游标之前必须声明和定义游标名称并将其与查询相关联(通常,查询会返回多行)。然后用户可以通过以下方式处理查询结果集:

使用open命令打开游标,使用fetch获取行,使用close关闭游标;

与隐式游标不同,可以通过名称引用显示游标或游标变量。因此,显式游标或游标变量称为命名游标。

3.1 声明和定义显式游标

用户可以首先声明一个显式游标,然后在同一个块,子程序或包中定义它;或者同时声明和定义它。

只声明游标,具有如下的语法:

CURSOR cursor_name [ parameter_list ] RETURN return_type;

声明游标并定义游标的语法:

CURSOR cursor_name [ parameter_list ] [ RETURN return_type ]  IS select_statement;

声明显式游标的例子:

DECLARE
 CURSOR c1 RETURN departments%ROWTYPE;    -- 声明C1

CURSOR c2 IS SELECT employee_id, job_id, salary -- 声明并且定义 c2

FROM employees

WHERE salary > 2000;

CURSOR c1 RETURN departments%ROWTYPE IS -- 定义 c1,-- 重复return type

SELECT * FROM departments

WHERE department_id = 110;

CURSOR c3 RETURN locations%ROWTYPE;      -- 声明c3

CURSOR c3 IS                     -- 定义c3,
-- 忽略 return type

SELECT * FROM locations

WHERE country_id = ‘JP‘;

BEGIN
 NULL;

END;
/

3.2 打开和关闭游标

声明和定义显式游标后,可以使用OPEN语句打开它;您使用CLOSE语句关闭一个打开的显式游标,从而允许重用其资源。关闭游标后,无法从其结果集中提取记录或引用其属性。

用户可以重新打开一个已经关闭的游标。游标在重新打开之间必须要被关闭。否则,PL/SQL会引发预定义异常CURSOR_ALREADY_OPEN.

3.3 使用显式游标获取数据

打开一个显式游标后,可以使用FETCH语句获取结果集。返回一行的FETCH语句的基本语法是:

FETCH cursor_name INTO into_clause

into_clause是一个变量列表或单个记录变量。 对于查询返回的每个列,变量列表或记录必须具有对应的类型兼容变量或字段。%TYPE和%ROWTYPE属性可用于声明变量和记录以在FETCH语句中使用。FETCH语句检索结果集的当前行,将该行的列值存储到变量或记录中,并将光标前移到下一行。通常,在LOOP语句中使用FETCH语句,当FETCH语句用完行时退出。 要检测此退出条件,请使用游标属性%NOTFOUND。因为当FETCH语句不返回任何行时,PL/SQL不会引发异常。

3.4 显式游标查询中的变量

显式游标查询可以引用其作用域中的任何变量。 当打开显式游标时,PL / SQL将评估查询中的任何变量,并在标识结果集时使用这些值。 稍后更改变量的值不会更改结果集。【定义游标时,游标中结果集就已经确定,如要改变结果集,必须关闭游标并重新打开游标】

3.5 当显式游标列需要别名时

当显式游标查询包含虚拟列(表达式)时,如果满足以下任一条件,则该列必须具有别名:

1、使用游标读取使用%ROWTYPE声明的记录。

2、需要引用虚拟列

3.6 接受参数的显示游标

用户可以创建具有形式参数的显式游标,然后在每次打开游标时将不同的实际参数传递到游标。 在游标查询中,可以在可以使用常量的任何位置使用正式的光标参数。在光标查询之外,用户不能引用正式的光标参数。

3.7 显示游标的属性

%ISOPEN  TRUE:游标打开状态;FALSE:其他状态。

%FOUND   NULL:显示游标打开但是还没有获取第一行

TRUE:从显式游标的最近一次提取返回了一行

FALSE:其他情况

%NOTFOUND NULL:显示游标打开但是还没有获取第一行

FALSE:从显式游标的最近一次提取返回了一行

TRUE:其他情况

%ROWCOUNT:在显式游标打开后但在第一次提取之前为零;否则就获取行数。

四、例子

4.1 获取tabs中表名称的两个例子

方法一:将结果集装在记录中

declare

--表行的记录变量

cursor mycur is select * from tabs;

cur_result tabs%rowtype;

begin

open mycur;--打开游标

loop

fetch mycur into cur_result;--获取数据

exit when mycur%notfound;--退出循环

dbms_output.put_line(‘The table name is ‘||cur_result.table_name);

end loop;

close mycur;--关闭游标

end;

方法二:将结果集装在变量中

declare

--变量

cursor mycur is select table_name from tabs;

v_tablename tabs.table_name%type;

begin

open mycur;--打开游标

loop

fetch mycur into v_tablename;--获取数据

exit when mycur%notfound;--退出循环

dbms_output.put_line(‘The table name is ‘||v_tablename);

end loop;

close mycur;--关闭游标

end;

方法三:将结果集装在游标类型的row%type中

declare

--表行的记录变量

cursor mycur is select table_name from tabs;

cur_result mycur%rowtype;

begin

open mycur;--打开游标

loop

fetch mycur into cur_result;--获取数据

exit when mycur%notfound;--退出循环

dbms_output.put_line(‘The table name is ‘||cur_result.table_name);

end loop;

close mycur;--关闭游标

end;

4.2 动态游标

静态游标的声明与定义必须在同一个块中执行,动态游标可以在begin之前声明游标,在打开游标时定义sql语句,即可以使用open cursor_name for sql_statement的形式打开游标。sql_statement可以是静态的SQL语句,也可以是动态的SQL语句。

例一:静态的SQL语句

declare

--表行的记录变量

type cursor_type is ref cursor;

mycur cursor_type;

cur_result tabs%rowtype;

begin

open mycur for select * from tabs;--打开游标

loop

fetch mycur into cur_result;--获取数据

exit when mycur%notfound;--退出循环

dbms_output.put_line(‘The table name is ‘||cur_result.table_name);

end loop;

close mycur;--关闭游标

end;

例二:动态的SQL语句

declare

type cursor_type is ref cursor;

mycur cursor_type;

cur_result tabs%rowtype;

v_sql varchar2(1000);

begin

v_sql:=‘select * from tabs‘;

open mycur for v_sql;--打开游标

loop

fetch mycur into cur_result;--获取数据

exit when mycur%notfound;--退出循环

dbms_output.put_line(‘The table name is ‘||cur_result.table_name);

end loop;

close mycur;--关闭游标

end;

五、其他说明

5.1 Oracle游标的官方文档

http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/static.htm#LNPLS00602

时间: 2024-10-13 12:37:23

【翻译】Oracle游标详细说明的相关文章

Oracle游标解析

本节对Oracle中的游标进行详细讲解. 本节所举实例来源Oracle中scott用户下的emp表dept表: 一.游标: 1.概念: 游标的本质是一个结果集resultset,主要用来临时存储从数据库中提取出来的数据块. 二.游标的分类: 1.显式游标:由用户定义,需要的操作:定义游标.打开游标.提取数据.关闭游标,主要用于对查询语句的处理. 属性:%FOUND        %NOTFOUND        %ISOPEN          %ROWCOUNT Example:打印emp表的

[转载]oracle游标概念讲解

原文URL:http://www.2cto.com/database/201203/122387.html ORACLE游标概念讲解 什么是游标?  ①从表中检索出结果集,从中每次指向一条记录进行交互的机制.      ②关系数据库中的操作是在完整的行集合上执行的.   由SELECT 语句返回的行集合包括满足该语句的WHERE 子句所列条件的所有行.由该语句返回完整的行集合叫做结果集.      应用程序,尤其是互动和在线应用程序,把完整的结果集作为一个单元处理并不总是有效的.      这些

Duang!危险的oracle游标

1.引言 SQL是面向集合的语言,其结果一般是集合量(含多条记录),而pl/sql的变量是标量,一组变量一次只能存放一条记录.很多时候查询结果的记录数是不确定的,无法提前声明足够的变量.于是引入了游标的概念,游标使得数据库操作更灵活,但同时也给黑客入侵数据库带来了机会.安华金和数据库安全实验室(DBSec Labs)基于游标的应用原理,本文讨论游标可能带来什么安全隐患以及如何应对这些安全隐患. 2.游标的分类 oracle数据库游标是Pl/sql执行DQL.DML等语句的时候,oracle在内存

ORACLE输出详细错误信息错误行数

... COMMIT; --输出成功信息 DBMS_OUTPUT.PUT_LINE('RUN RESULT: SUCCESS'); EXCEPTION WHEN OTHERS THEN BEGIN ROLLBACK; --输出错误信息 dbms_output.put_line(to_char(DBMS_UTILITY.format_error_backtrace) ||chr(10)||to_char(sqlcode) ||chr(10)||'ERROR '||SQLERRM); END; OR

基于RHEL 6.5安装Oracle 11g详细教程(1)——创建虚拟机

前 言 环境说明: 在本次实验当中,主要是实现基于RHEL 6.5 64bit系统成功安装Oracle 11g R2 64bit,实验平台基于VMware vSphere. 介质下载: VMware ESXi 5.5.0(1331820) 下载链接:http://yunpan.cn/QiBnp2xxpFjaD 访问密码 2ec0 Redhat Enterprise Linux 6.5 x86_64 下载链接:http://yunpan.cn/QiBXcFF5SXvBj 访问密码 467f Ora

oracle 游标例子

CREATE OR REPLACE PROCEDURE PRC_WAP_ACTIVEUSERS(RETCODE OUT VARCHAR2) /*********************************************************** * 功能:WAP指标--活跃用户统计(分批提交) * 参数:RETCODE(返回编码:0000成功) * 作者: * 创建时间:2013-01-16 * 版本:1.0 * 修改人: * 修改时间: ********************

Oracle游标—for、loop、if结合应用

一.需求 什么时候会用到Oracle游标,以及其中的for.loop.if呢? 先看这样一个需求: 有一张学生授课表T_TEACHING,每个学生都有数门课程: 主键ID(自增) 课程号COURSE_ID 学号USER_ID 1 01 201501 2 02 201501 3 03 201501 4 01 201502 5 01 201503 6 01 201504 7 02 201504 ... ... ... 但是因为某些原因,导致有的学生课程不全(本应该每个学生都有3门课),应该如何把不全

Oracle游标循环更新数据案例

declare v_XTXMBH number; v_ZJZJZJRQ varchar2(40); cursor c_job is SELECT XT.XTXMBH AS XTXMBH, QJ.ZJZJZJRQ AS ZJZJZJRQ FROM XTXMXX XT, QJGLXX_ZQL_MID QJ WHERE XT.XTXMBH = QJ.XTXMBH AND XT.XTXMCLRQ >= '20120630' AND (QJ.ZJQHZJRQ IS NULL OR QJ.ZJZJZJRQ

oracle游标小试

有时候需要大面积的修改数据,这个时候用循环语句效率不高.而临时表又不能满足点对点修改的时候,游标似一种不错的选择(PS:好像游标也是为循环而生的吧) 现在有两张表 t1(ryid number,name nvarchar2(50),salary number,paydate date……)用来存员工每月的工资 t2(ryid number,paySalary number)每个月发的工资数目 现将t2中的paySalary添加到t1中 可以直接用update来实现: 现用oracle的for游标