12、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表,表结构和数据参考: 

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

SQL> declare
  2       total_rows number(2);
  3  begin
  4       update customers
  5       set salary = salary + 500;
  6       if sql%notfound then
  7          dbms_output.put_line('没有找到客户信息!');
  8       elsif sql%found then
  9             total_rows := sql%rowcount;
 10             dbms_output.put_line('一共有: ' || total_rows || ' 个客户的工资被更新!');
 11      end if;
 12  end;
 13  /
一共有: 6 个客户的工资被更新!
PL/SQL procedure successfully completed

显式游标

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

创建显式游标的语法是 -

CURSOR cursor_name IS select_statement;

使用显式游标包括以下步骤 -

  • 声明游标初始化内存
  • 打开游标分配内存
  • 从游标获取数据
  • 关闭游标以释放分配的内存

声明游标

声明游标使用名称和相关的1SELECT1语句来定义游标。 例如 -

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;

示例

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

SQL> declare
  2          c_id customers.id%type;
  3          c_name customers.name%type;
  4          c_addr customers.address%type;
  5          cursor c_customers is
  6                 select id,name,address from customers;
  7  begin
  8          open c_customers;
  9          loop
 10          fetch c_customers into c_id,c_name,c_addr;
 11              exit when c_customers%notfound;
 12              dbms_output.put_line(c_id || ' ' || c_name || ' ' || c_addr );
 13          end loop;
 14          close c_customers;
 15  end;
 16  /
1 Ramesh Ahmedabad                
2 Khilan Delhi                    
3 kaushik Kota                     
4 Chaitali Mumbai                   
5 Hardik Bhopal                   
6 Komal MP                       
PL/SQL procedure successfully completed

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值