Oracle PL/SQL 游标:隐式、显式、For 循环示例
⚡ 智能摘要
光标 Oracle PL/SQL 游标是指向上下文区域的指针,该上下文区域保存着 SQL 语句返回的行。游标有两种类型:隐式游标,为 DML 自动创建;以及显式游标,由程序员声明和控制。

PL/SQL 中的 CURSOR 是什么?
光标是指向上下文区域的指针。 Oracle 创建用于处理上下文区域的 SQL 声明,此区域包含有关该声明的所有信息。
PL / SQL 允许程序员通过游标控制上下文区域。游标保存 SQL 语句返回的行,游标保存的行集合称为活动集。这些游标也可以命名,以便在代码的其他位置引用它们。
光标有两种类型:
- 隐式光标
- 显式光标
隐式光标
无论何时 DML操作 当数据库中发生操作时,会创建一个隐式游标来保存该操作影响的行。这些游标不能命名,因此无法在代码的其他位置进行控制或引用。我们只能通过游标属性来引用最近创建的游标。
显式光标
程序员可以创建命名上下文区域来执行 DML 操作,并对其进行更多控制。显式游标应在声明部分中定义。 PL/SQL 块它是为代码中需要使用的 SELECT 语句创建的。
以下是使用显式游标的步骤:
- 声明游标: 声明游标实际上就是为声明部分定义的 SELECT 语句创建一个命名的上下文区域。该上下文区域的名称与游标名称相同。
- 打开光标: 打开游标会指示 PL/SQL 为该游标分配内存,并使游标准备好提取记录。
- 从游标中获取数据: 在此过程中,执行 SELECT 语句,并将获取的行存储在已分配的内存中。这些行现在被称为活动集。从游标中获取数据是记录级操作,这意味着我们可以逐条记录地访问数据。每个 fetch 语句都会获取一个活动集,并保存该特定记录的信息。此语句与获取记录并将其赋值给 INTO 子句中变量的 SELECT 语句相同,但它不会抛出任何异常。 例外.
- 关闭光标: 一旦所有记录都被获取完毕,我们需要关闭游标,以便释放分配给此上下文区域的内存。
句法
DECLARE CURSOR <cursor_name> IS <SELECT statement>; <cursor_variable declaration>; BEGIN OPEN <cursor_name>; FETCH <cursor_name> INTO <cursor_variable>; . . CLOSE <cursor_name>; END;
在上述语法中,声明部分包含游标的声明以及用于存储提取数据的游标变量。游标是为游标声明中指定的 SELECT 语句创建的。在执行部分,声明的游标会被打开、提取数据并关闭。
游标属性
隐式游标和显式游标都具有一些可访问的属性。这些属性提供了有关游标操作的更多信息。以下列出了不同的游标属性及其用法。
| 游标属性 | 描述 |
|---|---|
| %成立 | 如果最近一次获取操作成功获取了记录,则返回布尔结果 TRUE;否则返回 FALSE。 |
| %未找到 | 与 %FOUND 的作用相反。如果最近一次获取操作未能获取到任何记录,则返回 TRUE。 |
| %开了 | 如果给定的光标已打开,则返回布尔结果 TRUE;否则返回 FALSE。 |
| %行数 | 返回一个数值,表示操作影响或获取的实际记录数。 |
显式游标示例: 在本示例中,我们将学习如何声明、打开、获取和关闭显式游标。我们将使用游标从 emp 表中获取所有员工姓名。我们还将使用游标属性来设置循环,使其从游标中获取所有记录。
下面的屏幕截图显示了此显式光标示例及其输出。 Oracle.
DECLARE CURSOR guru99_det IS SELECT emp_name FROM emp; lv_emp_name emp.emp_name%type; BEGIN OPEN guru99_det; LOOP FETCH guru99_det INTO lv_emp_name; IF guru99_det%NOTFOUND THEN EXIT; END IF; Dbms_output.put_line('Employee Fetched:'||lv_emp_name); END LOOP; Dbms_output.put_line('Total rows fetched is'||guru99_det%ROWCOUNT); CLOSE guru99_det; END; /
输出
Employee Fetched:BBB Employee Fetched:XXX Employee Fetched:YYY Total rows fetched is 3
Code 说明
- Code 第2行: 声明语句“SELECT emp_name FROM emp”的游标 guru99_det。
- Code 第3行: 声明变量 lv_emp_name %类型 锚定到 emp.emp_name。
- Code 第5行: 打开光标 guru99_det。
- Code 第6行: 设置基本循环语句以获取 emp 表中的所有记录。
- Code 第7行: 获取 guru99_det 数据并将值赋给 lv_emp_name。
- Code 第8行: 使用游标属性 %NOTFOUND 检查游标中的所有记录是否都已获取。如果已获取,则返回 TRUE,控制流退出循环;否则,控制流将继续从游标中获取数据并打印出来。
- Code 第10行: 循环语句的 EXIT 条件。
- Code 第12行: 打印获取的员工姓名。
- Code 第14行: 使用游标属性 %ROWCOUNT 查找游标获取的记录总数。
- Code 第15行: 循环结束后,光标关闭,已分配的内存被释放。
FOR 循环游标语句
光标 FOR循环 可用于处理游标。我们可以在 FOR 循环语句中指定游标名称而不是范围限制,这样循环就会从游标的第一个记录执行到最后一个记录。游标变量的创建、游标的打开、游标的读取和游标的关闭都由 FOR 循环隐式完成。
句法
DECLARE CURSOR <cursor_name> IS <SELECT statement>; BEGIN FOR I IN <cursor_name> LOOP . . END LOOP; END;
在上述语法中,声明部分包含游标的声明。该游标是为游标声明中指定的 SELECT 语句创建的。在执行部分,声明的游标被放置在 FOR 循环中,此时循环变量 'I' 充当游标变量。
Oracle 游标 for 循环示例: 在这个例子中,我们将使用游标 FOR 循环从 emp 表中投影出所有员工姓名。
DECLARE CURSOR guru99_det IS SELECT emp_name FROM emp; BEGIN FOR lv_emp_name IN guru99_det LOOP Dbms_output.put_line('Employee Fetched:'||lv_emp_name.emp_name); END LOOP; END; /
输出
Employee Fetched:BBB Employee Fetched:XXX Employee Fetched:YYY
Code 说明
- Code 第2行: 声明语句“SELECT emp_name FROM emp”的游标 guru99_det。
- Code 第4行: 使用循环变量 lv_emp_name 为游标构建 FOR 循环。
- Code 第6行: 在循环的每次迭代中打印员工姓名。
- Code 第7行: 退出循环(结束循环)。
注意: 在游标 FOR 循环中,不能使用游标属性,因为游标的打开、获取和关闭是由 FOR 循环隐式完成的。

