oracle游标

来源:互联网 发布:url编码 java 编辑:程序博客网 时间:2024/06/11 12:39
一  概念 
游标是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: 
Sql代码
[sql] view plaincopy
  1. Set Serveroutput on;  
  2.   
  3. begin  
  4.     update t_contract_master set liability_state = 1 where policy_code = '123456789';  
  5.       
  6.     if SQL%Found then  
  7.        dbms_output.put_line('the Policy is updated successfully.');  
  8.        commit;  
  9.     else  
  10.       dbms_output.put_line('the policy is updated failed.');  
  11.     end if;  
  12.   
  13. end;  
  14.   
  15. /  

在PL/SQL中run: 
Sql代码
[SQL] view plaincopy
  1. SQL>   
  2.    
  3. the policy is updated failed.  
  4.    
  5. 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) 
Sql代码

  

[sql] view plaincopy
  1. Set serveroutput on;  
  2.   
  3. declare   
  4.     ---define Cursor  
  5.     Cursor cur_policy is  
  6.      select cm.policy_code, cm.applicant_id, cm.period_prem,cm.bank_code,cm.bank_account  
  7.      from t_contract_master cm  
  8.      where cm.liability_state = 2  
  9.      and cm.policy_type = 1  
  10.      and cm.policy_cate in ('2','3','4')  
  11.      and rownum < 5  
  12.      order by cm.policy_code desc;  
  13.     curPolicyInfo cur_policy%rowtype;---定义游标变量  
  14. Begin  
  15.    open cur_policy; ---open cursor  
  16.    Loop   
  17.      --deal with extraction data from DB  
  18.      Fetch cur_policy into curPolicyInfo;  
  19.      Exit when cur_policy%notfound;  
  20.            
  21.      Dbms_Output.put_line(curPolicyInfo.policy_code);  
  22.    end loop;  
  23.    Exception   
  24.      when others then  
  25.          close cur_policy;  
  26.          Dbms_Output.put_line(Sqlerrm);  
  27.            
  28.    if cur_policy%isopen then    
  29.     --close cursor   
  30.       close cur_policy;  
  31.    end if;  
  32. end;  
  33.   
  34. /  


2) 
Sql代码
[sql] view plaincopy
  1. Set serveroutput on;  
  2.   
  3. declare   
  4.     Cursor cur_policy is  
  5.      select cm.policy_code, cm.applicant_id, cm.period_prem,cm.bank_code,cm.bank_account  
  6.      from t_contract_master cm  
  7.      where cm.liability_state = 2  
  8.      and cm.policy_type = 1  
  9.      and cm.policy_cate in ('2','3','4')  
  10.      and rownum < 5  
  11.      order by cm.policy_code desc;  
  12.      v_policyCode t_contract_master.policy_code%type;  
  13.      v_applicantId t_contract_master.applicant_id%type;  
  14.      v_periodPrem t_contract_master.period_prem%type;  
  15.      v_bankCode t_contract_master.bank_code%type;  
  16.      v_bankAccount t_contract_master.bank_account%type;  
  17. Begin  
  18.    open cur_policy;  
  19.    Loop   
  20.      Fetch cur_policy into v_policyCode,  
  21.                            v_applicantId,  
  22.                            v_periodPrem,  
  23.                            v_bankCode,  
  24.                            v_bankAccount;  
  25.      Exit when cur_policy%notfound;  
  26.            
  27.      Dbms_Output.put_line(v_policyCode);  
  28.    end loop;  
  29.    Exception   
  30.      when others then  
  31.          close cur_policy;  
  32.          Dbms_Output.put_line(Sqlerrm);  
  33.            
  34.    if cur_policy%isopen then     
  35.       close cur_policy;  
  36.    end if;  
  37. end;  
  38. /  


3)
Sql代码
[sql] view plaincopy
  1. Set serveroutput on;  
  2.   
  3. declare   
  4.     Cursor cur_policy is  
  5.      select cm.policy_code, cm.applicant_id, cm.period_prem,cm.bank_code,cm.bank_account  
  6.      from t_contract_master cm  
  7.      where cm.liability_state = 2  
  8.      and cm.policy_type = 1  
  9.      and cm.policy_cate in ('2','3','4')  
  10.      and rownum < 5  
  11.      order by cm.policy_code desc;  
  12. Begin  
  13.    For rec_Policy in cur_policy loop  
  14.        Dbms_Output.put_line(rec_policy.policy_code);  
  15.    end loop;  
  16.    Exception   
  17.      when others then  
  18.          Dbms_Output.put_line(Sqlerrm);  
  19.            
  20. end;  
  21.   
  22. /  

run pl/sql,执行结果如下: 
Sql代码  
  1. SQL>    
  2.     
  3. 8780203932   
  4. 8780203227   
  5. 8780203218   
  6. 8771289268   
  7.     
  8. PL/SQL procedure successfully completed  
[sql] view plaincopy
  1. SQL>   
  2.    
  3. 8780203932  
  4. 8780203227  
  5. 8780203218  
  6. 8771289268  
  7.    
  8. 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: 
Sql代码  
  1. Set serveroutput on;   
  2.   
  3. Declare  
  4.     ---define cursor type name   
  5.     type cur_type is ref cursor;   
  6.     cur_policy cur_type;   
  7.     sqlStr varchar2(500);   
  8.     rec_policy t_contract_master%rowtype;   
  9. begin  
  10.    ---define 动态Sql   
  11.    sqlStr := 'select cm.policy_code, cm.applicant_id, cm.period_prem,cm.bank_code,cm.bank_account from t_contract_master cm   
  12.      where cm.liability_state = 2    
  13.      and cm.policy_type = 1    
  14.      and cm.policy_cate in (2,3,4)    
  15.      and rownum < 5    
  16.      order by cm.policy_code desc ';   
  17. ---Open Cursor   
  18.   open cur_policy for sqlStr;   
  19.   loop   
  20.        fetch cur_policy into rec_policy.policy_code, rec_policy.applicant_id, rec_policy.period_prem,rec_policy.bank_code,rec_policy.bank_account;   
  21.        exit when cur_policy%notfound;   
  22.           
  23.        Dbms_Output.put_line('Policy_code:'||rec_policy.policy_code);   
  24.      
  25.   end loop;   
  26. close cur_policy;       
  27.   
  28. end;   
  29. /  
[sql] view plaincopy
  1. Set serveroutput on;  
  2.   
  3. Declare  
  4.     ---define cursor type name  
  5.     type cur_type is ref cursor;  
  6.     cur_policy cur_type;  
  7.     sqlStr varchar2(500);  
  8.     rec_policy t_contract_master%rowtype;  
  9. begin  
  10.    ---define 动态Sql  
  11.    sqlStr := 'select cm.policy_code, cm.applicant_id, cm.period_prem,cm.bank_code,cm.bank_account from t_contract_master cm  
  12.      where cm.liability_state = 2   
  13.      and cm.policy_type = 1   
  14.      and cm.policy_cate in (2,3,4)   
  15.      and rownum < 5   
  16.      order by cm.policy_code desc ';  
  17. ---Open Cursor  
  18.   open cur_policy for sqlStr;  
  19.   loop  
  20.        fetch cur_policy into rec_policy.policy_code, rec_policy.applicant_id, rec_policy.period_prem,rec_policy.bank_code,rec_policy.bank_account;  
  21.        exit when cur_policy%notfound;  
  22.          
  23.        Dbms_Output.put_line('Policy_code:'||rec_policy.policy_code);  
  24.     
  25.   end loop;  
  26. close cur_policy;      
  27.   
  28. end;  
  29. /  


4.常见Exception 
Sql代码
  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   SELECTINTO…语句返回多于一行的数据      
  10. NO_DATA_FOUND   ORA_01403   SELECTINTO…语句没有数据返回      
  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   在连接时提供了无效用户名或口令   
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 断奶后乳房有硬块怎么办 断奶了有硬块疼怎么办 断奶时乳房有硬块怎么办 憋奶乳房有硬块怎么办 回奶以后有硬块怎么办 回奶里面有肿块怎么办 回奶时候的硬块怎么办 回奶乳房有硬块怎么办 回奶胀痛有硬块怎么办 回奶期间有硬块怎么办 回奶期间乳房有硬块怎么办 回奶乳房有肿块怎么办 牛犊子出生3天喘怎么办 猪高烧不退不吃怎么办 苹果6刷机失败怎么办 uc能看不能下怎么办 苹果6s铃声太小怎么办 苹果6铃声声音小怎么办 苹果7来电铃声小怎么办 红米手机声音小怎么办 微信安装不上去怎么办 6s无法安装微信怎么办 苹果4微信版本低怎么办 新手机没有微信怎么办 新手机登陆微信怎么办 新号码被注册过怎么办 微信注册不了怎么办啊 苹果4铃声不响怎么办 苹果6黑屏没反应怎么办 苹果7卡机黑屏了怎么办 苹果7手机铃声小怎么办 支付宝发现套现怎么办 空调滴水管断了怎么办 地漏下水管断了怎么办 脸上长白色糠疹怎么办 腋下长白色的毛怎么办 饥荒电羊死光了怎么办 6s储存空间虚满怎么办 大胸下垂穿婚纱怎么办 美团签约成功后怎么办 拍婚纱照笑不出来怎么办