📜  PL / SQL-游标

📅  最后修改于: 2020-11-26 05:57:11             🧑  作者: Mango


在本章中,我们将讨论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语句一起使用。下表提供了最常用的属性的描述-

S.No Attribute & Description
1

%FOUND

Returns TRUE if an INSERT, UPDATE, or DELETE statement affected one or more rows or a SELECT INTO statement returned one or more rows. Otherwise, it returns FALSE.

2

%NOTFOUND

The logical opposite of %FOUND. It returns TRUE if an INSERT, UPDATE, or DELETE statement affected no rows, or a SELECT INTO statement returned no rows. Otherwise, it returns FALSE.

3

%ISOPEN

Always returns FALSE for implicit cursors, because Oracle closes the SQL cursor automatically after executing its associated SQL statement.

4

%ROWCOUNT

Returns the number of rows affected by an INSERT, UPDATE, or DELETE statement, or returned by a SELECT INTO statement.

如以下示例所示,将以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. 

如果您查看客户表中的记录,您会发现行已更新-

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 customer.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.