每当在PL/SQL中执行一个SQL语时,Oracle数据库都会为这个语句分一个上下文区域(Context Area)来处理所必需的信息,其中包括语句处理的行数,一个指向语句被分析以后的表示形式的指针以及查询的结果集。游标是指向上下文区域的句柄或指针,PL/SQL通过游标可以控制或处理上下文区域。如果按照游标是否绑定到一个专门的查询语句来划分,可以分为静态游标和动态游标。其中静态游标又分为:隐式游标和显示游标;动态游标分为:强类型和弱类型。
1.隐式游标
每当我们执行一个DML语句(包括INSERT,UPDATE,MERGE或者DELETE)或者SELECT INTO语句时,PL/SQL都会声明一个隐式游标并管理这个游标。这种游标之所以叫做隐式游标,是因为数据库自动执行游标相关操作,比如,打开,提取,关闭等。隐式游标又叫做SQL游标。
1.1隐式游标属性
隐式游标属性返回有关DDL语句和DML语句执行的信息,该游标属性值总是返回最近执行的SQL语句。执行打开的隐式游标的属性值是空的。隐式游标可用的属性如下:
隐式游标属性
名 字
说 明
SQL%FOUND
|
如果取到记录就返回TRUE,否者返回FLASE
|
SQL%NOTFOUND
|
如果没有取得记录就返回TRUE,否者返回FALSE
|
SQL%ROWCOUNT
|
返回从游标中取出的记录数
|
SQL%ISOPEN
|
由于隐式游标总是自动打开和关闭,因此这个属性中是FALSE
|
隐式游标属性总是返回最后一次执行的SQL语句的属性值,而不管这个SQL语句时在哪个代码块或者程序中执行的。
declare
v_empno emp.empno%type := 3792;
begin
update emp e set e.sal = 5000 where e.empno = v_empno;
if sql%notfound then
insert into emp
(empno, ename, hiredate, sal, deptno)
values
(v_empno, 'CHICLEWU', date '2011-07-08', 4000, 50);
end if;
end;
1.2使用隐式游标属性准则
当使用隐式游标属性是,需要考虑以下准则:
2.显示游标
当你需要精确地控制查询处理时,可以在任何PL/SQL块、子程序或者包的声明部分显示地声明一个游标。显示游标就是在代码的声明部分明确定义的SELECT语句,并同时指定一个名字。然后你可以通过三个语句来控制游标:OPEN、FETCH和CLOSE。首先,你需要使用OPEN语句初始化游标,标识结果集。然后,可以反复地执行FETCH语句直到所有行都被取出,或者使用BULK COLLECT语句一次性取出所有行。最后,只用CLOSE语句释放游标。
2.1声明显示游标
要使用显示游标,必须先在PL/SQL块或包的规范部分声明它。
CURSOR cursor_name
[ ( cursor_parameter_declaration [, cursor_parameter_declaration ]... )]
[ RETURN rowtype] IS select_statement ;
其中,cusor_name是显示游标的名字;cursor_parameter_declartion是显示游标的参数,是可选项;select_statement是显示游标指定的SELECT语句。
2.2打开显示游标
OPEN cursor_name
[ ( cursor_parameter_name [ [,] cursor_parameter_name ]... ) ] ;
其中,cusor_name是显示游标的名字;cursor_parameter_name是显示游标的参数,是可选项。如果游标声明时,指定了游标参数,则打开时一定要指定该参数。
2.3提取数据
每次只提取一行数据:
FETCH cursor_name
INTO[(variable_name [, variable_name ]... | record_name )];
一次提取多行数据:
FETCH cursor_name
BULK COLLECT INTO [(collection_name [,collection_name...])];
2.4关闭显示游标
CLOSE cursor_name;
2.5显示游标属性
每个显示游标和游标变量都有四个属性:%FOUND、%NOTFOUND、%ROWCOUNT和%ISOPEN。可以下面的语法使用这些属性:
cusor%attribute
其中,cursor就是我们声明的游标名字或者游标变量。
显示游标属性
名 字
说 明
cusor%FOUND
|
如果取到记录就返回TRUE,否者返回FLASE
|
cusor%NOTFOUND
|
如果没有取得记录就返回TRUE,否者返回FALSE
|
cusor%ROWCOUNT
|
返回当值从指定游标取得的记录数量
|
cusor%ISOPEN
|
如果游标时打开的则返回TRUE,否则返回FALE
|
2.6显示游标例子
2.6.1不带参数的显示游标
declare
cursor cur_emp is
select e.ename, e.sal from emp e where e.deptno = 10; --声明游标
v_ename emp.ename%type;
v_sal emp.sal%type;
begin
open cur_emp; --打开游标
--循环取出
loop
fetch cur_emp
into v_ename, v_sal; --提取记录
exit when cur_emp%notfound;
dbms_output.put_line(v_ename || '的工资是' || v_sal);
end loop;
close cur_emp; --关闭游标
end;
2.6.2带参数参数的显示游标
declare
cursor cur_emp(p_empno number) is
select e.ename, e.sal from emp e where e.empno = p_empno; --声明游标
v_empno emp.empno%type := 7788;
v_ename emp.ename%type;
v_sal emp.sal%type;
begin
open cur_emp(v_empno); --打开游标
--循环取出
loop
fetch cur_emp
into v_ename, v_sal; --提取记录
exit when cur_emp%notfound;
dbms_output.put_line(v_ename || '的工资是' || v_sal);
end loop;
close cur_emp; --关闭游标
end;
2.6.3一次取出所有记录
declare
cursor cur_emp is
select e.ename, e.sal from emp e where e.deptno = 10; --声明游标
type it_ename is table of emp.ename%type index by binary_integer;
type it_sal is table of emp.sal%type index by binary_integer;
vit_ename it_ename;
vit_sal it_sal;
begin
open cur_emp; --打开游标
fetch cur_emp bulk collect
into vit_ename, vit_sal; --一次性取出所有记录
close cur_emp; --关闭游标
for i in vit_ename.first .. vit_ename.last loop
dbms_output.put_line(vit_ename(i) || '的工资是' || vit_sal(i));
end loop;
end;
3.游标变量
游标变量是指向或者引用底层游标的变量。显示游标已经为结果集的工作区指定了名字,而游标变量只是指向这个工作区的引用。显示游标和隐式游标都绑定到一个专门的查询语句,而游标变量可以是任何一个查询语句,也可以是查询语句的字符串变量或者字面量。因为游标变量的查询语句可以是多个不相同的查询,因此这种游标称为动态游标。显示游标和隐式游标称为静态游标。
3.1声明REF CURSOR类型
TYPE cursor_type_name IS REF CURSOR [RETURN return_type];
其中,cursor_type_name是游标类型的名字;return_type是该游标类型返回的数据类型。
REF CURSOR类型可是强类型(带有return)或者是弱类型(不带return)。以下两种声明都是有效的声明:
TYPE rc_emp is REF CURSOR RETURN emp%rowtype; --强类型
TYPE rc_emp is REF CURSOR;--弱类型
3.2声明游标变量
cursor_variable_name cursor_type_name;
其中,cursor_variable_name是游标变量的名字;cursor_type_name是之前的REF CURSOR声明的游标类型的名字。
3.3打开游标变量
OPEN cursor_variable_name FOR select_statement;
其中,cursor_variable_name是游标变量的名字; select_statement可以是一个直接的SQL语句,也可以一个SELECT语句的字符串或者字面。如果select_statement是字符串或者字面量,可以包含绑定变量的占位符,并可以使用USING子句标识相应的占位符值。
3.4提取数据
每次只提取一行数据:
FETCH cursor_name
INTO [(variable_name [, variable_name ]... | record_name )];
一次提取多行数据:
FETCH cursor_name
BULK COLLECT INTO [(collection_name [,collection_name...])];
3.5关闭显示游标
CLOSE cursor_name;
3.6游标变量属性
游标变量属性与显示游标属性一样,参见2.5
3.7游标变量例子
3.7.1一次只取一行记录
declare
type rc_emp is ref cursor; --声明ref游标类型
vrc_emp rc_emp; --声明游标变量
v_ename emp.ename%type;
v_sal emp.sal%type;
begin
open vrc_emp for
select e.ename, e.sal from emp e where e.deptno = 10; --打开游标变量,并赋值。
loop
fetch vrc_emp
into v_ename, v_sal; --提取记录
exit when vrc_emp%notfound;
dbms_output.put_line(v_ename || '的工资是' || v_sal);
end loop;
close vrc_emp; ---关闭游标变量
end;
3.7.2一次取出所有行记录
declare
type it_ename is table of emp.ename%type index by binary_integer;
type it_sal is table of emp.sal%type index by binary_integer;
type rc_emp is ref cursor; --声明ref游标类型\
vrc_emp rc_emp; --声明游标变量
vit_ename it_ename;
vit_sal it_sal;
v_ename emp.ename%type;
v_sal emp.sal%type;
begin
open vrc_emp for
select e.ename, e.sal from emp e where e.deptno = 10; --打开游标变量,并赋值。
fetch vrc_emp bulk collect
into vit_ename, vit_sal; --一次性取出所有记录
close vrc_emp; --关闭游标
for i in vit_ename.first .. vit_ename.last loop
dbms_output.put_line(vit_ename(i) || '的工资是' || vit_sal(i));
end loop;
end;
3.7.3查询语句是字符串变量
declare
type rc_emp is ref cursor; --声明ref游标类型
vrc_emp rc_emp; --声明游标变量
v_ename emp.ename%type;
v_sal emp.sal%type;
v_deptno emp.deptno%type := 10;
v_sql clob;
begin
v_sql := 'select e.ename, e.sal from emp e where e.deptno = :deptno';
open vrc_emp for v_sql
using v_deptno; --打开游标变量,并赋值。
loop
fetch vrc_emp
into v_ename, v_sal; --提取记录
exit when vrc_emp%notfound;
dbms_output.put_line(v_ename || '的工资是' || v_sal);
end loop;
close vrc_emp; ---关闭游标变量
end;
4.游标表达式
游标表达式返回一个嵌套游标,使用CUSOR操作符表示。可以使用游标表达式从一个或者多个表中提取庞大的复杂的记录集。
可以在下面的场合使用游标表达式:
- 显示游标声明
- REF CURSOR声明和REF CURSOR变量
- 动态SQL查询
游标表达式语法:
CURSOR (subquery)
当父游标提取数据时,嵌套游标就会隐式地打开。嵌套游标在以下这些时刻关闭:
- 用户显示地关闭嵌套游标
- 父游标再次执行
- 父游标关闭
- 父游标取消
- 从父游标提取数据时抛出了异常。嵌套游标会和父游标一起关闭
使用游标表达式,查询各个部门的名称、地址以及该部门下的员工:
declare
cursor cur_dept_emp is
select d.dname,
d.loc,
cursor (select * from emp e where e.deptno = d.deptno) nc_emp --嵌套游标
from dept d;
type rc_emp is ref cursor return emp%rowtype;
vrc_emp rc_emp;
vrt_emp emp%rowtype;
v_dname dept.dname%type;
v_loc dept.loc%type;
begin
open cur_dept_emp;
loop
fetch cur_dept_emp
into v_dname, v_loc, vrc_emp; --提取父游标数据,并自动打开嵌套游标
exit when cur_dept_emp%notfound;
dbms_output.put_line(v_loc || '的' || v_dname || '部门的员工信息:');
loop
fetch vrc_emp
into vrt_emp; --从嵌套游标提取数据
exit when vrc_emp%notfound;
dbms_output.put_line(vrt_emp.ename || '的工资' || vrt_emp.sal);
end loop;
dbms_output.put_line('');
end loop;
close cur_dept_emp; --关闭父游标,同时也关闭了嵌套游标
end;
5.游标FOR循环
游标FOR循环的迭代变量不需要事先声明。这是一个%ROWTYPE记录,其字段名称匹配查询的列名,而且只能存在于循环中。数据库自动打开、提取、关闭游标FOR循环。即使在循环中使用EXIT语句、GO语句或者抛出异常,数据库都会自动关闭该游标。游标FOR循环可以分为:隐式游标FOR循环和显示游标FOR循环。
5.1隐式游标FOR循环
begin
--隐式游标FOR循环
for vrc_emp in (select * from emp e where e.deptno = 10) loop
dbms_output.put_line(vrc_emp.ename || '的工资' || vrc_emp.sal);
end loop;
end;
5.2显示游标FOR循环
declare
cursor cur_emp is
select * from emp e where e.deptno = 10;
begin
--隐式游标FOR循环
for vrc_emp in cur_emp loop
dbms_output.put_line(vrc_emp.ename || '的工资' || vrc_emp.sal);
end loop;
end;
6.WHERE CURRENT OF语句
PL/SQL为游标的UPDATE和DELETE语句提供了WHERE CURRENT OF语句。当你声明一个在UPDATE或者DELETE语句的CURRENT OF子句引用的游标时,必须使用FOR UPDATE语句获取独立的行级锁。
要修改最新取出来的记录的列:
UPDATEtable_name
SET set_clause
WHERE CURRENT OF cursor_name;
要删除最新取出的记录:
DELETE FORM table_name WHERE CURRENT OF cursor_name;
declare
cursor cur_emp is
select * from emp for update nowait;
vrt_emp emp%rowtype;
begin
open cur_emp;
loop
fetch cur_emp
into vrt_emp;
exit when cur_emp%notfound;
if vrt_emp.ename = 'SCOTT' then
update emp e set e.sal = 6000 where current of cur_emp; --注意current of 后面子游标,而不是记录
end if;
if vrt_emp.ename = 'CHICLEWU' then
delete from emp where current of cur_emp;
end if;
end loop;
end;
分享到:
相关推荐
五、PL/SQL游标 游标用于处理单行结果集。声明游标后,可以使用FETCH语句获取结果集中的行,并通过%ROWTYPE属性将结果映射到记录变量。 六、PL/SQL异常处理 异常处理使用BEGIN...EXCEPTION结构,可以捕获并处理运行...
### PL/SQL 详解 #### 1. PL/SQL程序设计简介 ##### 1.1 SQL与PL/SQL **1.1.1 什么是PL/SQL?** PL/SQL (Procedure Language / Structured Query Language) 是Oracle为SQL语言添加的过程化特性的一种编程语言。它...
在这个"PL/SQL使用详解"中,我们可以期待学习到关于PL/SQL的基础概念、语法结构以及在实际开发中的应用。 一、PL/SQL基础 PL/SQL由三部分组成:声明部分(DECLARATION)、执行部分(EXECUTION)和异常处理部分...
PL/SQL中的游标部分解释了如何使用游标来访问和操作结果集。游标是一个内存中的数据结构,它允许开发者逐行遍历SQL查询的结果。游标是处理多行数据的常用方法,特别是在涉及到复杂的查询操作时。 异常错误处理部分...
### PL/SQL基础编程知识点详解 #### 一、PL/SQL概述 PL/SQL,全称为Procedural Language for SQL,是Oracle数据库特有的高级程序设计语言。它结合了SQL的数据处理能力和传统编程语言的控制结构,使开发者能够在...
【PL/SQL例子详解】 PL/SQL,全称Procedural Language/Structured Query Language,是Oracle数据库中的一个扩展,结合了SQL的查询能力与过程化编程语言的特点,为数据库管理和开发提供了强大的工具。本资源“PL/SQL...
这个PDF文件很可能是PL/SQL Developer 7.0的官方用户手册或教程,包含了详细的软件介绍、安装步骤、功能详解以及实例演示。它是开发者深入理解并有效利用这款工具的重要参考资料。 总结,PL/SQL Developer 7.0是...
游标是PL/SQL处理单行结果集的重要工具。它们允许你逐行访问查询结果,通过声明游标变量、打开游标、提取数据和关闭游标来实现。游标在处理复杂数据交互和迭代遍历数据库记录时非常有用。 异常处理是PL/SQL程序健壮...
### PL/SQL编程基础知识点详解 #### 一、PL/SQL简介 PL/SQL是Oracle专有的编程语言,它是对标准SQL的扩展,主要用于Oracle数据库的程序开发。它结合了SQL的数据操纵能力和过程化编程语言的控制结构,使得在数据库...
Oracle PL/SQL编程详解主要涵盖了数据库编程的关键方面,旨在帮助开发者深入理解如何利用PL/SQL进行高效、模块化的数据库应用开发。PL/SQL是Oracle数据库系统专用的一种过程化编程语言,它结合了SQL的查询能力并扩展...
在"第七章.doc"中,你可能会学习到关于PL/SQL的更高级主题,比如递归、游标的高级用法、存储过程的参数传递、复合类型以及PL/SQL与数据库并发控制的机制。每个实例都是精心设计的,旨在帮助你理解和掌握这些概念,...
### PL/SQL存储过程编程详解 #### 一、Oracle应用编辑方法概览 在Oracle数据库的应用开发中,存在多种编辑方法和技术,它们各有特点和适用场景。以下是对这些方法的概述: 1. **Pro*C/C++**: 这是一种C语言与...
### PL/SQL详解:从入门到精通 #### 一、PL/SQL简介 PL/SQL(Procedure Language for SQL)是一种过程化语言,专为Oracle数据库设计。它将SQL语句与传统的程序流程控制结构相结合,使得开发人员能够在数据库内部...
我们可以从中提取到关于PL/SQL语言及其对数据库交互作用的丰富知识点,本知识点详解将围绕以下几个方面展开:PL/SQL基本操作、PL/SQL处理数据库记录、游标(Cursor)的概念及其在PL/SQL中的使用。 1. PL/SQL基本...
### PL/SQL教程知识点详解 #### 一、PL/SQL程序设计简介 PL/SQL,全称Procedure Language for SQL,是Oracle数据库专有的程序设计语言,用于增强SQL的功能,实现复杂的业务逻辑处理。PL/SQL结合了SQL的数据操作...
1. **掌握PL/SQL的数据类型和基本语法**:理解PL/SQL中不同数据类型的定义与使用方法,包括字符串类型等。 2. **熟悉控制结构与游标的使用**:学习如何利用控制结构如循环、条件判断等进行逻辑控制;了解游标的基本...
【PL/SQL 入门详解】 PL/SQL(Procedural Language/Structured Query Language)是Oracle公司为标准SQL添加的编程扩展,它被深度集成到Oracle数据库系统中,成为数据库管理和开发的重要工具。PL/SQL提供了更丰富的...
### 精通Oracle PL/SQL:核心知识点详解 #### 一、Oracle PL/SQL简介与重要性 Oracle PL/SQL(程序包SQL)是一种专为Oracle数据库设计的过程化语言,它结合了SQL命令和过程化的编程结构。本书《精通Oracle PL/SQL:...
### PL/SQL 常量与变量详解 #### 一、引言 PL/SQL(Procedural Language for SQL)是Oracle数据库的标准编程语言,它将过程化代码块与SQL命令相结合,允许开发者编写功能强大的应用程序。在PL/SQL中,理解和掌握...
### PL/SQL 个人笔记详解 #### 一、PL/SQL 块中可嵌入的 SQL 语句类型 PL/SQL(程序化SQL)是Oracle数据库的标准编程语言,它扩展了SQL的功能,允许在数据库环境中编写过程化的业务逻辑。在PL/SQL中,可以嵌入多种...