- PL/SQL 教程
- PL/SQL - 首页
- PL/SQL - 概述
- PL/SQL - 环境
- PL/SQL - 基本语法
- PL/SQL - 数据类型
- PL/SQL - 变量
- PL/SQL - 常量和文字
- PL/SQL - 运算符
- PL/SQL - 条件
- PL/SQL - 循环
- PL/SQL - 字符串
- PL/SQL - 数组
- PL/SQL - 过程
- PL/SQL - 函数
- PL/SQL - 游标
- PL/SQL - 记录
- PL/SQL - 异常
- PL/SQL - 触发器
- PL/SQL - 包
- PL/SQL - 集合
- PL/SQL - 事务
- PL/SQL - 日期和时间
- PL/SQL - DBMS 输出
- PL/SQL - 面向对象
- PL/SQL 有用的资源
- PL/SQL - 问题与解答
- PL/SQL - 快速指南
- PL/SQL - 有用的资源
- PL/SQL - 讨论
PL/SQL - 游标
在本章中,我们将讨论 PL/SQL 中的游标。Oracle 为处理 SQL 语句创建一个称为上下文区域的内存区域,其中包含处理该语句所需的所有信息,例如处理的行数等。
游标是指向此上下文区域的指针。PL/SQL 通过游标来控制上下文区域。游标保存由 SQL 语句返回的行(一个或多个)。游标所保存的这组行称为活动集。
你可以命名游标,以便在程序中引用它来一次获取 SQL 语句返回的行并处理它们。有两种类型的游标 -
- 隐式游标
- 显式游标
隐式游标
当对没有该语句的显式游标执行 SQL 语句时,Oracle 会自动创建隐式游标。程序员无法控制隐式游标和其中的信息。
只要发出 DML 语句(INSERT、UPDATE 和 DELETE),就会有一个隐式游标与该语句关联。对于 INSERT 操作,该游标会保存需要插入的数据。对于 UPDATE 和 DELETE 操作,该游标会标识将受到影响的行。
在 PL/SQL 中,你可以将最近的隐式游标称为SQL 游标,它始终具有%FOUND、%ISOPEN、%NOTFOUND和%ROWCOUNT等属性。SQL 游标具有附加属性%BULK_ROWCOUNT和%BULK_EXCEPTIONS,这些属性专用于FORALL语句。下表提供了常用属性的说明-
序号 | 属性和说明 |
---|---|
1 | %FOUND 如果 INSERT、UPDATE 或 DELETE 语句影响了一行或多行,或者 SELECT INTO 语句返回了一行或多行,则返回 TRUE。否则,将返回 FALSE。 |
2 | %NOTFOUND 与 %FOUND 逻辑相反。如果 INSERT、UPDATE 或 DELETE 语句没有影响任何行,或者 SELECT INTO 语句没有返回任何行,则返回 TRUE。否则,将返回 FALSE。 |
3 | %ISOPEN 对于隐式游标始终返回 FALSE,因为 Oracle 会在执行其关联的 SQL 语句后自动关闭 SQL 游标。 |
4 | %ROWCOUNT 返回 INSERT、UPDATE 或 DELETE 语句影响的行数,或者 SELECT INTO 语句返回的行数。 |
可以像下面示例中所示,通过sql%attribute_name来访问任何 SQL 游标属性。
示例
我们将使用我们在前几章中创建和使用的 CUSTOMERS 表。
Select * from customers; +----+----------+-----+-----------+----------+ | ID | NAME | AGE | ADDRESS | SALARY | +----+----------+-----+-----------+----------+ | 1 | Ramesh | 32 | Ahmedabad | 2000.00 | | 2 | Khilan | 25 | Delhi | 1500.00 | | 3 | kaushik | 23 | Kota | 2000.00 | | 4 | Chaitali | 25 | Mumbai | 6500.00 | | 5 | Hardik | 27 | Bhopal | 8500.00 | | 6 | Komal | 22 | MP | 4500.00 | +----+----------+-----+-----------+----------+
以下程序将更新该表并使每个客户的薪水增加 500,并使用SQL%ROWCOUNT属性来确定受影响的行数 -
DECLARE total_rows number(2); BEGIN UPDATE customers SET salary = salary + 500; IF sql%notfound THEN dbms_output.put_line('no customers selected'); ELSIF sql%found THEN total_rows := sql%rowcount; dbms_output.put_line( total_rows || ' customers selected '); END IF; END; /
当在 SQL 提示符下执行以上代码时,会产生以下结果 −
6 customers selected PL/SQL procedure successfully completed.
如果检查 customers 表中的记录,将会发现行已更新 −
Select * from customers; +----+----------+-----+-----------+----------+ | ID | NAME | AGE | ADDRESS | SALARY | +----+----------+-----+-----------+----------+ | 1 | Ramesh | 32 | Ahmedabad | 2500.00 | | 2 | Khilan | 25 | Delhi | 2000.00 | | 3 | kaushik | 23 | Kota | 2500.00 | | 4 | Chaitali | 25 | Mumbai | 7000.00 | | 5 | Hardik | 27 | Bhopal | 9000.00 | | 6 | Komal | 22 | MP | 5000.00 | +----+----------+-----+-----------+----------+
显式游标
显式游标由程序员定义,用以获得对上下文区域的更多控制权。应该在 PL/SQL 块的声明部分中定义显式游标。在返回多行的 SELECT 语句上创建它。
创建显式游标的语法为 −
CURSOR cursor_name IS select_statement;
使用显式游标包括以下步骤 −
- 声明游标以初始化内存
- 打开游标以分配内存
- 获取游标以检索数据
- 关闭游标以释放已分配的内存
声明游标
声明游标是使用名称和关联的 SELECT 语句来定义游标。例如 −
CURSOR c_customers IS SELECT id, name, address FROM customers;
打开游标
打开游标会为其分配内存,并使其准备好向其中获取 SQL 语句返回的行。例如,我们将按照以下方式打开上述已定义游标 −
OPEN c_customers;
获取游标
获取游标涉及一次访问一行。例如,我们将按照以下方式从上述已打开游标中获取行 −
FETCH c_customers INTO c_id, c_name, c_addr;
关闭游标
关闭游标意味着释放已分配的内存。例如,我们将按照以下方式关闭上述已打开游标 −
CLOSE c_customers;
示例
以下是一个完整的示例,用以说明显式游标 &minua 的概念;
DECLARE c_id customers.id%type; c_name customers.name%type; c_addr customers.address%type; CURSOR c_customers is SELECT id, name, address FROM customers; BEGIN OPEN c_customers; LOOP FETCH c_customers into c_id, c_name, c_addr; EXIT WHEN c_customers%notfound; dbms_output.put_line(c_id || ' ' || c_name || ' ' || c_addr); END LOOP; CLOSE c_customers; END; /
当在 SQL 提示符下执行以上代码时,会产生以下结果 −
1 Ramesh Ahmedabad 2 Khilan Delhi 3 kaushik Kota 4 Chaitali Mumbai 5 Hardik Bhopal 6 Komal MP PL/SQL procedure successfully completed.