PL/SQL 专题
您的位置:database > PL/SQL专题 > PL/SQL游标
PL/SQL游标
作者:--    发布时间:2019-11-20

在本章中,我们将讨论和学习pl/sql中的游标。 oracle创建一个称为上下文区域的内存区域,用于处理sql语句,它包含处理该语句所需的所有信息; 例如,处理的行数等。

游标是指向此上下文区域的指针。pl/sql通过游标控制上下文区域,游标保存sql语句返回的行(一个或多个)。 游标所在的行集称为活动集。

可以命名一个游标,以便在程序中引用它来获取和处理sql语句返回的行,一次处理一个(行)。pl/sql中有两种类型的游标 -

  • 隐式游标
  • 显式游标

隐式游标

当执行sql语句时,如果语句没有显式游标,则oracle会自动创建隐式游标。程序员无法控制隐式游标及其信息。

每当发出dml语句(insertupdatedelete)时,隐式游标与此语句相关联。 对于insert操作,游标保存需要插入的数据。对于updatedelete操作,游标标识将受到影响的行。

在pl/sql中,可以将最近的隐式游标引用为sql游标,它始终具有%found%isopen%notfound%rowcount等属性。 sql游标具有额外的属性%bulk_rowcount%bulk_exceptions,旨在与forall语句一起使用。下表提供了游标中最常用属性的描述 -

编号 属性 描述
1 %found 如果insertupdatedelete语句影响一行或多行,或老兄select into语句返回一行或多行,则返回true,否则返回false
2 %notfound %found的逻辑相反。 如果insert,update或delete语句没有影响任何行,或select into语句未返回任何行,则返回true。 否则返回false。
3 %isopen 由于oracle在执行关联的sql语句后会自动关闭sql游标,因此总是为隐式游标返回false
4 %rowcount 返回受insertupdatedelete语句,或者受select into语句影响的行数。

任何sql游标属性将被访问为sql%attribute_name,如下例所示。

示例

这里将使用在前几章中创建和使用的customers表,表结构和数据参考: http://www.h3.com/plsql/plsql_variable_types.html

create table customers( 
   id   int not null, 
   name varchar (20) not null, 
   age int not null, 
   address char (25), 
   salary   decimal (18, 2),        
   primary key (id) 
);

-- 插入数据
insert into customers (id,name,age,address,salary) 
values (1, 'ramesh', 32, 'ahmedabad', 2000.00 );  

insert into customers (id,name,age,address,salary) 
values (2, 'khilan', 25, 'delhi', 1500.00 );  

insert into customers (id,name,age,address,salary) 
values (3, 'kaushik', 23, 'kota', 2000.00 );

insert into customers (id,name,age,address,salary) 
values (4, 'chaitali', 25, 'mumbai', 6500.00 ); 

insert into customers (id,name,age,address,salary) 
values (5, 'hardik', 27, 'bhopal', 8500.00 );  

insert into customers (id,name,age,address,salary) 
values (6, 'komal', 22, 'mp', 4500.00 );

以下程序将表中每个客户的工资增加500,并使用sql%rowcount属性来确定受影响的行数 -

set serveroutput on size 99999;
declare  
   total_rows number(2); 
begin 
   update customers 
   set salary = salary + 500; 
   if sql%notfound then 
      dbms_output.put_line('没有找到客户信息~'); 
   elsif sql%found then 
      total_rows := sql%rowcount;
      dbms_output.put_line('一共有:' || total_rows || ' 个客户的工资被更新! '); 
   end if;  
end; 
/

执行上面示例代码,得到以下结果 -

如果查询了客户表中的记录,会发现工资已更新(增加了500) -

sql> select id,name,salary from customers;

        id name                     salary
---------- -------------------- ----------
         1 ramesh                     2500
         2 khilan                     2000
         3 kaushik                    2500
         4 chaitali                   7000
         5 hardik                     9000
         6 komal                      5000

显式游标

显式游标是用于获得对上下文区域的更多控制的程序员定义的游标。应在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;

示例

以下是一个完整的例子来说明显式游标的概念。

set serveroutput on size 99999;
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; 
/

执行上面示例代码,得到以下结果 -


网站声明:
本站部分内容来自网络,如您发现本站内容
侵害到您的利益,请联系本站管理员处理。
联系站长
373515719@qq.com
关于本站:
编程参考手册