`
zpball
  • 浏览: 917040 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Oracle中Cursor介绍

阅读更多
一  概念
游标是SQL的一个内存工作区,由系统或用户以变量的形式定义。游标的作用就是用于临时存储从数据库中提取的数据块。在某些情况下,需要把数据从存放在磁盘的表中调到计算机内存中进行处理,最后将处理结果显示出来或最终写回数据库。这样数据处理的速度才会提高,否则频繁的磁盘数据交换会降低效率。
二  类型
  Cursor类型包含三种: 隐式Cursor,显式Cursor和Ref Cursor(动态Cursor)。
1. 隐式Cursor:
1).对于Select …INTO…语句,一次只能从数据库中获取到一条数据,对于这种类型的DML Sql语句,就是隐式Cursor。例如:Select /Update / Insert/Delete操作。
2)作用:可以通过隐式Cusor的属性来了解操作的状态和结果,从而达到流程的控制。Cursor的属性包含:
SQL%ROWCOUNT 整型 代表DML语句成功执行的数据行数
SQL%FOUND  布尔型  值为TRUE代表插入、删除、更新或单行查询操作成功
SQL%NOTFOUND 布尔型 与SQL%FOUND属性返回值相反
SQL%ISOPEN 布尔型 DML执行过程中为真,结束后为假
3) 隐式Cursor是系统自动打开和关闭Cursor.
下面是一个Sample:
 
Set Serveroutput on;   
  
begin  
    update t_contract_master set liability_state = 1 where policy_code = '123456789';   
       
    if SQL%Found then  
       dbms_output.put_line('the Policy is updated successfully.');   
       commit;   
    else  
      dbms_output.put_line('the policy is updated failed.');   
    end if;   
  
end;   
  
/  

Set Serveroutput on;

begin
    update t_contract_master set liability_state = 1 where policy_code = '123456789';
    
    if SQL%Found then
       dbms_output.put_line('the Policy is updated successfully.');
       commit;
    else
      dbms_output.put_line('the policy is updated failed.');
    end if;

end;

/
在PL/SQL中run:
SQL>    
    
the policy is updated failed.   
    
PL/SQL procedure successfully completed  

SQL> 
 
the policy is updated failed.
 
PL/SQL procedure successfully completed

2. 显式Cursor:
(1) 对于从数据库中提取多行数据,就需要使用显式Cursor。显式Cursor的属性包含:
游标的属性   返回值类型   意    义 
%ROWCOUNT   整型  获得FETCH语句返回的数据行数 
%FOUND  布尔型 最近的FETCH语句返回一行数据则为真,否则为假 
%NOTFOUND   布尔型 与%FOUND属性返回值相反 
%ISOPEN 布尔型 游标已经打开时值为真,否则为假 

(2) 对于显式游标的运用分为四个步骤:
 定义游标---Cursor  [Cursor Name]  IS;
 打开游标---Open  [Cursor Name];
 操作数据---Fetch  [Cursor name]
 关闭游标---Close [Cursor Name],这个Step绝对不可以遗漏。
(3)以下是三种常见显式Cursor用法。
1)
Set serveroutput on;   
  
declare    
    ---define Cursor   
    Cursor cur_policy is  
     select cm.policy_code, cm.applicant_id, cm.period_prem,cm.bank_code,cm.bank_account   
     from t_contract_master cm   
     where cm.liability_state = 2   
     and cm.policy_type = 1   
     and cm.policy_cate in ('2','3','4')   
     and rownum < 5   
     order by cm.policy_code desc;   
    curPolicyInfo cur_policy%rowtype;---定义游标变量   
Begin  
   open cur_policy; ---open cursor   
   Loop    
     --deal with extraction data from DB   
     Fetch cur_policy into curPolicyInfo;   
     Exit when cur_policy%notfound;   
            
     Dbms_Output.put_line(curPolicyInfo.policy_code);   
   end loop;   
   Exception    
     when others then  
         close cur_policy;   
         Dbms_Output.put_line(Sqlerrm);   
            
   if cur_policy%isopen then     
    --close cursor    
      close cur_policy;   
   end if;   
end;   
  
/  

Set serveroutput on;

declare 
    ---define Cursor
    Cursor cur_policy is
     select cm.policy_code, cm.applicant_id, cm.period_prem,cm.bank_code,cm.bank_account
     from t_contract_master cm
     where cm.liability_state = 2
     and cm.policy_type = 1
     and cm.policy_cate in ('2','3','4')
     and rownum < 5
     order by cm.policy_code desc;
    curPolicyInfo cur_policy%rowtype;---定义游标变量
Begin
   open cur_policy; ---open cursor
   Loop 
     --deal with extraction data from DB
     Fetch cur_policy into curPolicyInfo;
     Exit when cur_policy%notfound;
         
     Dbms_Output.put_line(curPolicyInfo.policy_code);
   end loop;
   Exception 
     when others then
         close cur_policy;
         Dbms_Output.put_line(Sqlerrm);
         
   if cur_policy%isopen then  
	--close cursor 
      close cur_policy;
   end if;
end;

/

2)
Set serveroutput on;   
  
declare    
    Cursor cur_policy is  
     select cm.policy_code, cm.applicant_id, cm.period_prem,cm.bank_code,cm.bank_account   
     from t_contract_master cm   
     where cm.liability_state = 2   
     and cm.policy_type = 1   
     and cm.policy_cate in ('2','3','4')   
     and rownum < 5   
     order by cm.policy_code desc;   
     v_policyCode t_contract_master.policy_code%type;   
     v_applicantId t_contract_master.applicant_id%type;   
     v_periodPrem t_contract_master.period_prem%type;   
     v_bankCode t_contract_master.bank_code%type;   
     v_bankAccount t_contract_master.bank_account%type;   
Begin  
   open cur_policy;   
   Loop    
     Fetch cur_policy into v_policyCode,   
                           v_applicantId,   
                           v_periodPrem,   
                           v_bankCode,   
                           v_bankAccount;   
     Exit when cur_policy%notfound;   
            
     Dbms_Output.put_line(v_policyCode);   
   end loop;   
   Exception    
     when others then  
         close cur_policy;   
         Dbms_Output.put_line(Sqlerrm);   
            
   if cur_policy%isopen then      
      close cur_policy;   
   end if;   
end;   
/  

Set serveroutput on;

declare 
    Cursor cur_policy is
     select cm.policy_code, cm.applicant_id, cm.period_prem,cm.bank_code,cm.bank_account
     from t_contract_master cm
     where cm.liability_state = 2
     and cm.policy_type = 1
     and cm.policy_cate in ('2','3','4')
     and rownum < 5
     order by cm.policy_code desc;
     v_policyCode t_contract_master.policy_code%type;
     v_applicantId t_contract_master.applicant_id%type;
     v_periodPrem t_contract_master.period_prem%type;
     v_bankCode t_contract_master.bank_code%type;
     v_bankAccount t_contract_master.bank_account%type;
Begin
   open cur_policy;
   Loop 
     Fetch cur_policy into v_policyCode,
                           v_applicantId,
                           v_periodPrem,
                           v_bankCode,
                           v_bankAccount;
     Exit when cur_policy%notfound;
         
     Dbms_Output.put_line(v_policyCode);
   end loop;
   Exception 
     when others then
         close cur_policy;
         Dbms_Output.put_line(Sqlerrm);
         
   if cur_policy%isopen then   
      close cur_policy;
   end if;
end;
/


3)Sql代码
Set serveroutput on;   
  
declare    
    Cursor cur_policy is  
     select cm.policy_code, cm.applicant_id, cm.period_prem,cm.bank_code,cm.bank_account   
     from t_contract_master cm   
     where cm.liability_state = 2   
     and cm.policy_type = 1   
     and cm.policy_cate in ('2','3','4')   
     and rownum < 5   
     order by cm.policy_code desc;   
Begin  
   For rec_Policy in cur_policy loop   
       Dbms_Output.put_line(rec_policy.policy_code);   
   end loop;   
   Exception    
     when others then  
         Dbms_Output.put_line(Sqlerrm);   
            
end;   
  
/  

Set serveroutput on;

declare 
    Cursor cur_policy is
     select cm.policy_code, cm.applicant_id, cm.period_prem,cm.bank_code,cm.bank_account
     from t_contract_master cm
     where cm.liability_state = 2
     and cm.policy_type = 1
     and cm.policy_cate in ('2','3','4')
     and rownum < 5
     order by cm.policy_code desc;
Begin
   For rec_Policy in cur_policy loop
       Dbms_Output.put_line(rec_policy.policy_code);
   end loop;
   Exception 
     when others then
         Dbms_Output.put_line(Sqlerrm);
         
end;

/


run pl/sql,执行结果如下:
SQL>    
    
8780203932   
8780203227   
8780203218   
8771289268   
    
PL/SQL procedure successfully completed  

SQL> 
 
8780203932
8780203227
8780203218
8771289268
 
PL/SQL procedure successfully completed

3. Ref Cursor(动态游标):
1) 与隐式Cursor,显式Cursor的区别:Ref Cursor是可以通过在运行期间传递参数来获取数据结果集。而另外两种Cursor,是静态的,在编译期间就决定数据结果集。
2) Ref cursor的使用:
 Type [Cursor type name] is ref cursor
 Define 动态的Sql语句
 Open cursor
 操作数据---Fetch  [Cursor name]
 Close Cursor
下面是一个Sample:
Set serveroutput on;   
  
Declare  
    ---define cursor type name   
    type cur_type is ref cursor;   
    cur_policy cur_type;   
    sqlStr varchar2(500);   
    rec_policy t_contract_master%rowtype;   
begin  
   ---define 动态Sql   
   sqlStr := 'select cm.policy_code, cm.applicant_id, cm.period_prem,cm.bank_code,cm.bank_account from t_contract_master cm   
     where cm.liability_state = 2    
     and cm.policy_type = 1    
     and cm.policy_cate in (2,3,4)    
     and rownum < 5    
     order by cm.policy_code desc ';   
---Open Cursor   
  open cur_policy for sqlStr;   
  loop   
       fetch cur_policy into rec_policy.policy_code, rec_policy.applicant_id, rec_policy.period_prem,rec_policy.bank_code,rec_policy.bank_account;   
       exit when cur_policy%notfound;   
          
       Dbms_Output.put_line('Policy_code:'||rec_policy.policy_code);   
     
  end loop;   
close cur_policy;       
  
end;   
/  

Set serveroutput on;

Declare
    ---define cursor type name
    type cur_type is ref cursor;
    cur_policy cur_type;
    sqlStr varchar2(500);
    rec_policy t_contract_master%rowtype;
begin
   ---define 动态Sql
   sqlStr := 'select cm.policy_code, cm.applicant_id, cm.period_prem,cm.bank_code,cm.bank_account from t_contract_master cm
     where cm.liability_state = 2 
     and cm.policy_type = 1 
     and cm.policy_cate in (2,3,4) 
     and rownum < 5 
     order by cm.policy_code desc ';
---Open Cursor
  open cur_policy for sqlStr;
  loop
       fetch cur_policy into rec_policy.policy_code, rec_policy.applicant_id, rec_policy.period_prem,rec_policy.bank_code,rec_policy.bank_account;
       exit when cur_policy%notfound;
       
       Dbms_Output.put_line('Policy_code:'||rec_policy.policy_code);
  
  end loop;
close cur_policy;    

end;
/

4.常见Exception
 
1.  错 误 名 称 错误代码    错 误 含 义      
2.  CURSOR_ALREADY_OPEN ORA_06511   试图打开已经打开的游标      
3.  INVALID_CURSOR  ORA_01001   试图使用没有打开的游标      
4.  DUP_VAL_ON_INDEX    ORA_00001   保存重复值到惟一索引约束的列中      
5.  ZERO_DIVIDE ORA_01476   发生除数为零的除法错误      
6.  INVALID_NUMBER  ORA_01722   试图对无效字符进行数值转换      
7.  ROWTYPE_MISMATCH    ORA_06504   主变量和游标的类型不兼容      
8.  VALUE_ERROR ORA_06502   转换、截断或算术运算发生错误      
9.  TOO_MANY_ROWS   ORA_01422   SELECT…INTO…语句返回多于一行的数据      
10. NO_DATA_FOUND   ORA_01403   SELECT…INTO…语句没有数据返回      
11. TIMEOUT_ON_RESOURCE ORA_00051   等待资源时发生超时错误      
12. TRANSACTION_BACKED_OUT  ORA_00060   由于死锁,提交失败      
13. STORAGE_ERROR   ORA_06500   发生内存错误      
14. PROGRAM_ERROR   ORA_06501   发生PL/SQL内部错误      
15. NOT_LOGGED_ON   ORA_01012   试图操作未连接的数据库      
16. LOGIN_DENIED    ORA_01017   在连接时提供了无效用户名或口令    

分享到:
评论

相关推荐

    Oracle中Cursor介绍[归类].pdf

    Oracle中的Cursor,也称为游标,是数据库管理系统中一个重要的概念,主要用于处理SQL查询返回的多行结果集。游标提供了一种方式,允许程序逐行处理查询结果,而不是一次性加载所有数据。以下是对游标分类及其特性的...

    oracle-cursor.rar_cursor_oracle_oracle cursor

    下面将详细介绍Oracle游标的工作原理、类型以及如何在实际开发中应用。 1. 游标的工作原理 游标(Cursor)本质上是一种指针,它指向结果集中的特定行。当我们执行一个SELECT语句时,系统会返回一个结果集,游标则...

    Oracle数据库中的Cursor介绍

    ### Oracle数据库中的Cursor详解 #### 一、游标的基本概念 **游标(Cursor)**是Oracle数据库中的一个重要特性,主要用于处理SQL查询返回的结果集。它允许应用程序以更灵活的方式逐行处理查询结果,而非一次性处理...

    pkg_XXX.rar_oracle_oracle record cursor

    在Oracle数据库系统中,"pkg_XXX.rar_oracle_oracle record cursor" 提供了一个学习和参考的案例,涉及到了存储过程、游标(cursor)、记录(record)以及动态SQL和临时表的使用。这些概念是Oracle数据库编程的核心...

    在Oracle 9i下的display_cursor脚本

    在Oracle数据库中,游标(Cursor)是一种处理单条记录的数据对象,常用于循环执行SQL语句。当一个PL/SQL块或者存储过程执行一个SELECT语句时,Oracle会隐式或显式地打开一个游标来处理结果集。`DISPLAY_CURSOR`脚本...

    oracle-cursor.rar_oracle

    Oracle游标是数据库管理系统中一个重要的概念,它在处理复杂SQL操作时扮演着核心角色。游标允许我们按行处理查询结果集,而非一次性加载所有数据。这在处理大量数据或者进行迭代处理时非常有用,因为可以有效地管理...

    oracle cursor 实例

    oracle中游标的使用方法,便于初学者参考,精通人员欢迎指正在。

    oracle 临时表使用例子并用CURSOR返回结果集的例子

    Oracle数据库系统是世界上最广泛使用的数据库管理系统之一,尤其在企业级应用中占据主导地位。临时表在Oracle中扮演着重要的角色,它们主要用于存储在会话期间临时产生的数据,这些数据只对当前会话可见,会话结束后...

    Java获取Oracle存储过程返回的Cursor

    本篇文章将详细介绍如何在Java中通过ODBC6驱动获取Oracle存储过程返回的Cursor。 首先,我们需要创建一个Oracle存储过程,该过程定义了一个名为CURSOR_RESULT的REF CURSOR类型。在提供的示例中,我们有一个名为TEST...

    ORACLE技术文档\oracle cursor 游标.doc

    Oracle游标,或称为光标,是数据库管理系统中用于处理SQL查询的一种机制,它允许程序逐行处理查询结果。在Oracle中,游标是至关重要的,尤其在进行复杂的交互式数据操作时。当一个应用程序尝试打开过多的游标时,...

    oracle CURSOR例子

    在Oracle数据库管理中,游标(Cursor)是一种强大的工具,用于处理SQL语句返回的结果集中的数据。游标允许程序逐一访问结果集中的每一行记录,并进行复杂的逻辑处理。本文将通过几个示例详细介绍Oracle中游标的使用...

    java调用oracle存储过程返回结果集,Record,cursor参照.pdf

    本文介绍了Java调用Oracle存储过程返回结果集Record和Cursor的相关知识点,包括创建Type、PACKAGE和PROCEDURE,Java代码中调用存储过程,并获取结果集。这些知识点对深入了解Oracle存储过程和Java调用Oracle存储过程...

    Oracle JOB,procedure,cursor 的使用

    本篇文章将深入探讨Oracle中的JOB、PROCEDURE(存储过程)和CURSOR(游标)的使用,这些是Oracle数据库开发中的核心概念。 首先,我们来看Oracle中的JOB。JOB是一种调度工具,允许用户在特定时间或间隔执行数据库...

    Oracle 中使用 fetch bulk collect into 批量效率的读取游标数据

    Oracle 中使用 fetch bulk collect into 批量效率的读取游标数据 Oracle 中的游标数据读取是数据库开发中非常常见的操作。通常,我们使用 fetch some_cursor into var1, var2 形式来获取游标数据,当游标中的记录数...

    cx_Oracle-7.3.0_oracle_cx_oracle_cx_Oracle7.3对应_python_jupyteror

    标题中的"cx_Oracle-7.3.0_oracle_cx_oracle_cx_Oracle7.3对应_python_jupyteror" 提到了一个关键的Python库——cx_Oracle,它是Python与Oracle数据库之间的一个接口,允许Python程序员使用Oracle的全部功能。...

    cx_Oracle使用手册

    cx_Oracle是Python编程语言中用于连接Oracle数据库的一个模块。该模块遵循Python数据库API规范,并且适用于Oracle 11.2和12.1版本,同时兼容Python 2.x和3.x版本。cx_Oracle模块通过使用Oracle客户端库来实现与...

    大型项目Oracle sql,function,procedures,package,cursor,job

    标题和描述中提到的“大型项目Oracle sql,function,procedures,package,cursor,job”涉及的是Oracle数据库管理和开发的核心概念。以下是对这些概念的详细解释: 1. **SQL(Structured Query Language)**:SQL...

    Python连接oracle工具cx_Oracle官方文档

    在cx_Oracle版本6中,为对象类型提供了更多的支持,并且介绍了对象类型相关的对象、高级队列选项以及消息属性等。 对于希望了解cx_Oracle版本历史的用户,官方文档也提供了详细的发布说明。例如,cx_Oracle 6.0版本...

    修改后的oracle游标总结,比较的全面

    Oracle 游标是 PL/SQL 中的一种重要概念,用于查询数据库,获取记录集合(结果集)的指针。游标可以分为静态游标和动态游标两种。 静态游标 静态游标可以分为显示游标和隐式游标两种。 显示游标 显示游标是使用 ...

    oracle笔记游标的使用

    oracle笔记游标的使用,游标的详细代码案例,游标知识点笔记!

Global site tag (gtag.js) - Google Analytics