PL/SQL 游标

2024年11月21日 PL/SQL 游标 极客笔记

PL/SQL 游标

当处理SQL语句时,Oracle会创建一个称为上下文区域的内存区域。光标是指向这个上下文区域的指针。它包含处理该语句所需的所有信息。在PL/SQL中,上下文区域由光标控制。光标包含了关于一个SELECT语句以及被该语句访问的数据行的信息。

光标用于引用一个程序,以逐个获取和处理由SQL语句返回的行。有两种类型的光标:

  • 隐式光标
  • 显式光标

PL/SQL隐式游标

当执行一个SQL语句时,如果你没有为该语句使用显式光标,Oracle会自动生成隐式光标。

默认情况下,这些光标用于处理类似INSERT、UPDATE、DELETE等DML语句。

Oracle提供了一些属性,称为隐式光标属性,用于检查DML操作的状态。其中一些属性包括:%FOUND、%NOTFOUND、%ROWCOUNT和%ISOPEN。

例如: 当你执行像INSERT、UPDATE、DELETE这样的SQL语句时,光标属性会告诉你是否受影响的行以及受影响的行数。如果在PL/SQL块中运行SELECT INTO语句,则可以使用隐式光标属性来确定SELECT语句是否返回了任何行。如果没有选择任何数据,它将返回一个错误。

下表说明了每个光标属性的状态:

属性 描述
%FOUND 如果DML语句如INSERT、DELETE和UPDATE影响至少一行或多行,或者SELECT INTO语句返回一行或多行,则其返回值为TRUE。否则返回FALSE。
%NOTFOUND 如果DML语句如INSERT、DELETE和UPDATE不影响任何行,或者SELECT INTO语句不返回任何行,则其返回值为TRUE。否则返回FALSE。它与%FOUND正好相反。
%ISOPEN 对于隐式游标,它始终返回FALSE,因为SQL游标在执行其关联的SQL语句后会自动关闭。
%ROWCOUNT 它返回被DML语句如INSERT、DELETE和UPDATE影响的行数,或者被SELECT INTO语句返回的行数。

PL/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 + 5000;
   IF sql%notfound THEN
      dbms_output.put_line('no customers updated');
   ELSIF sql%found THEN
      total_rows := sql%rowcount;
      dbms_output.put_line( total_rows || ' customers updated ');
   END IF; 
END;
/

当在SQL提示符下执行上述代码时,它产生以下结果 –

6 customers updated
PL/SQL procedure successfully completed.

现在,如果你检查顾客表的记录,你会发现行已经被更新了。

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显式游标

显式游标由程序员定义,以获得对上下文区域更多的控制。这些游标应该在PL/SQL块的声明部分中定义。它是在返回多行的SELECT语句上创建的。

显式游标的语法

以下是创建显式游标的语法:

CURSOR cursor_name IS select_statement;;

步骤

在使用显示游标时,您必须遵循以下步骤。

  1. 声明游标以在内存中进行初始化。
  2. 打开游标以分配内存。
  3. 从游标中检索数据。
  4. 关闭游标以释放分配的内存。

声明游标

定义具有名称和相关SELECT语句的游标。

显式游标声明的语法

CURSOR name IS
 SELECT statement; 

打开游标

用于为游标分配内存,并使得能够将SQL语句返回的行轻松地获取到其中。

游标打开的语法:

OPEN cursor_name;

检索游标

用于逐行访问数据。您可以按以下方式从上述打开的游标中检索行:

游标检索的语法:

FETCH cursor_name INTO variable_list;

关闭游标

用于释放分配的内存。使用以下语法关闭上述已打开的游标。

游标关闭的语法:

Close cursor_name;

PL/SQL 显式游标示例

以下是一个完整的示例,用于说明显式游标的概念。

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  Allahabad
2  Suresh  Kanpur
3  Mahesh  Ghaziabad
4  Chandan  Noida
5  Alex  Paris
6  Sunita  Delhi
PL/SQL procedure successfully completed. 

本文链接:http://so.lmcjl.com/news/18237/

展开阅读全文