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;;
步骤
在使用显示游标时,您必须遵循以下步骤。
- 声明游标以在内存中进行初始化。
- 打开游标以分配内存。
- 从游标中检索数据。
- 关闭游标以释放分配的内存。
声明游标
定义具有名称和相关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.