cursor 小结

2024-09-03 22:58
文章标签 小结 cursor

本文主要是介绍cursor 小结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

原创作者: hwhuang 阅读:21120次 评论:0条 更新时间:2011-06-01
关键字
概念
类型
异常处理

一 概念
游标是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代码 复制代码 收藏代码
  1. Set Serveroutput on;
  2. begin
  3. update t_contract_master set liability_state = 1 where policy_code = '123456789';
  4. if SQL%Found then
  5. dbms_output.put_line('the Policy is updated successfully.');
  6. commit;
  7. else
  8. dbms_output.put_line('the policy is updated failed.');
  9. end if;
  10. end;
  11. /
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代码 复制代码 收藏代码
  1. SQL>
  2. the policy is updated failed.
  3. 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代码 复制代码 收藏代码
  1. Set serveroutput on;
  2. declare
  3. ---define Cursor
  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. curPolicyInfo cur_policy%rowtype;---定义游标变量
  13. Begin
  14. open cur_policy; ---open cursor
  15. Loop
  16. --deal with extraction data from DB
  17. Fetch cur_policy into curPolicyInfo;
  18. Exit when cur_policy%notfound;
  19. Dbms_Output.put_line(curPolicyInfo.policy_code);
  20. end loop;
  21. Exception
  22. when others then
  23. close cur_policy;
  24. Dbms_Output.put_line(Sqlerrm);
  25. if cur_policy%isopen then
  26. --close cursor
  27. close cur_policy;
  28. end if;
  29. end;
  30. /
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)
Sql代码 复制代码 收藏代码
  1. Set serveroutput on;
  2. declare
  3. Cursor cur_policy is
  4. select cm.policy_code, cm.applicant_id, cm.period_prem,cm.bank_code,cm.bank_account
  5. from t_contract_master cm
  6. where cm.liability_state = 2
  7. and cm.policy_type = 1
  8. and cm.policy_cate in ('2','3','4')
  9. and rownum < 5
  10. order by cm.policy_code desc;
  11. v_policyCode t_contract_master.policy_code%type;
  12. v_applicantId t_contract_master.applicant_id%type;
  13. v_periodPrem t_contract_master.period_prem%type;
  14. v_bankCode t_contract_master.bank_code%type;
  15. v_bankAccount t_contract_master.bank_account%type;
  16. Begin
  17. open cur_policy;
  18. Loop
  19. Fetch cur_policy into v_policyCode,
  20. v_applicantId,
  21. v_periodPrem,
  22. v_bankCode,
  23. v_bankAccount;
  24. Exit when cur_policy%notfound;
  25. Dbms_Output.put_line(v_policyCode);
  26. end loop;
  27. Exception
  28. when others then
  29. close cur_policy;
  30. Dbms_Output.put_line(Sqlerrm);
  31. if cur_policy%isopen then
  32. close cur_policy;
  33. end if;
  34. end;
  35. /
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代码 复制代码 收藏代码
  1. Set serveroutput on;
  2. declare
  3. Cursor cur_policy is
  4. select cm.policy_code, cm.applicant_id, cm.period_prem,cm.bank_code,cm.bank_account
  5. from t_contract_master cm
  6. where cm.liability_state = 2
  7. and cm.policy_type = 1
  8. and cm.policy_cate in ('2','3','4')
  9. and rownum < 5
  10. order by cm.policy_code desc;
  11. Begin
  12. For rec_Policy in cur_policy loop
  13. Dbms_Output.put_line(rec_policy.policy_code);
  14. end loop;
  15. Exception
  16. when others then
  17. Dbms_Output.put_line(Sqlerrm);
  18. end;
  19. /
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代码 复制代码 收藏代码
  1. SQL>
  2. 8780203932
  3. 8780203227
  4. 8780203218
  5. 8771289268
  6. 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:
Sql代码 复制代码 收藏代码
  1. Set serveroutput on;
  2. Declare
  3. ---define cursor type name
  4. type cur_type is ref cursor;
  5. cur_policy cur_type;
  6. sqlStr varchar2(500);
  7. rec_policy t_contract_master%rowtype;
  8. begin
  9. ---define 动态Sql
  10. sqlStr := 'select cm.policy_code, cm.applicant_id, cm.period_prem,cm.bank_code,cm.bank_account from t_contract_master cm
  11. where cm.liability_state = 2
  12. and cm.policy_type = 1
  13. and cm.policy_cate in (2,3,4)
  14. and rownum < 5
  15. order by cm.policy_code desc ';
  16. ---Open Cursor
  17. open cur_policy for sqlStr;
  18. loop
  19. fetch cur_policy into rec_policy.policy_code, rec_policy.applicant_id, rec_policy.period_prem,rec_policy.bank_code,rec_policy.bank_account;
  20. exit when cur_policy%notfound;
  21. Dbms_Output.put_line('Policy_code:'||rec_policy.policy_code);
  22. end loop;
  23. close cur_policy;
  24. end;
  25. /
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
Sql代码 复制代码 收藏代码
  1. 1. 错 误 名 称 错误代码 错 误 含 义
  2. 2. CURSOR_ALREADY_OPEN ORA_06511 试图打开已经打开的游标
  3. 3. INVALID_CURSOR ORA_01001 试图使用没有打开的游标
  4. 4. DUP_VAL_ON_INDEX ORA_00001 保存重复值到惟一索引约束的列中
  5. 5. ZERO_DIVIDE ORA_01476 发生除数为零的除法错误
  6. 6. INVALID_NUMBER ORA_01722 试图对无效字符进行数值转换
  7. 7. ROWTYPE_MISMATCH ORA_06504 主变量和游标的类型不兼容
  8. 8. VALUE_ERROR ORA_06502 转换、截断或算术运算发生错误
  9. 9. TOO_MANY_ROWS ORA_01422 SELECTINTO…语句返回多于一行的数据
  10. 10. NO_DATA_FOUND ORA_01403 SELECTINTO…语句没有数据返回
  11. 11. TIMEOUT_ON_RESOURCE ORA_00051 等待资源时发生超时错误
  12. 12. TRANSACTION_BACKED_OUT ORA_00060 由于死锁,提交失败
  13. 13. STORAGE_ERROR ORA_06500 发生内存错误
  14. 14. PROGRAM_ERROR ORA_06501 发生PL/SQL内部错误
  15. 15. NOT_LOGGED_ON ORA_01012 试图操作未连接的数据库
  16. 16. LOGIN_DENIED ORA_01017 在连接时提供了无效用户名或口令

这篇关于cursor 小结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1134287

相关文章

mybatis映射器配置小结

《mybatis映射器配置小结》本文详解MyBatis映射器配置,重点讲解字段映射的三种解决方案(别名、自动驼峰映射、resultMap),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定... 目录select中字段的映射问题使用SQL语句中的别名功能使用mapUnderscoreToCame

Vue和React受控组件的区别小结

《Vue和React受控组件的区别小结》本文主要介绍了Vue和React受控组件的区别小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录背景React 的实现vue3 的实现写法一:直接修改事件参数写法二:通过ref引用 DOMVu

Vite 打包目录结构自定义配置小结

《Vite打包目录结构自定义配置小结》在Vite工程开发中,默认打包后的dist目录资源常集中在asset目录下,不利于资源管理,本文基于Rollup配置原理,本文就来介绍一下通过Vite配置自定义... 目录一、实现原理二、具体配置步骤1. 基础配置文件2. 配置说明(1)js 资源分离(2)非 JS 资

Java Stream 并行流简介、使用与注意事项小结

《JavaStream并行流简介、使用与注意事项小结》Java8并行流基于StreamAPI,利用多核CPU提升计算密集型任务效率,但需注意线程安全、顺序不确定及线程池管理,可通过自定义线程池与C... 目录1. 并行流简介​特点:​2. 并行流的简单使用​示例:并行流的基本使用​3. 配合自定义线程池​示

Java实现复杂查询优化的7个技巧小结

《Java实现复杂查询优化的7个技巧小结》在Java项目中,复杂查询是开发者面临的“硬骨头”,本文将通过7个实战技巧,结合代码示例和性能对比,手把手教你如何让复杂查询变得优雅,大家可以根据需求进行选择... 目录一、复杂查询的痛点:为何你的代码“又臭又长”1.1冗余变量与中间状态1.2重复查询与性能陷阱1.

Go之errors.New和fmt.Errorf 的区别小结

《Go之errors.New和fmt.Errorf的区别小结》本文主要介绍了Go之errors.New和fmt.Errorf的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考... 目录error的基本用法1. 获取错误信息2. 在条件判断中使用基本区别1.函数签名2.使用场景详细对

C#异步编程ConfigureAwait的使用小结

《C#异步编程ConfigureAwait的使用小结》本文介绍了异步编程在GUI和服务器端应用的优势,详细的介绍了async和await的关键作用,通过实例解析了在UI线程正确使用await.Conf... 异步编程是并发的一种形式,它有两大好处:对于面向终端用户的GUI程序,提高了响应能力对于服务器端应

MySQL慢查询工具的使用小结

《MySQL慢查询工具的使用小结》使用MySQL的慢查询工具可以帮助开发者识别和优化性能不佳的SQL查询,本文就来介绍一下MySQL的慢查询工具,具有一定的参考价值,感兴趣的可以了解一下... 目录一、启用慢查询日志1.1 编辑mysql配置文件1.2 重启MySQL服务二、配置动态参数(可选)三、分析慢查

c++日志库log4cplus快速入门小结

《c++日志库log4cplus快速入门小结》文章浏览阅读1.1w次,点赞9次,收藏44次。本文介绍Log4cplus,一种适用于C++的线程安全日志记录API,提供灵活的日志管理和配置控制。文章涵盖... 目录简介日志等级配置文件使用关于初始化使用示例总结参考资料简介log4j 用于Java,log4c

gorm乐观锁使用小结

《gorm乐观锁使用小结》本文主要介绍了gorm乐观锁使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录前言grom乐观锁机制gorm乐观锁依赖安装gorm乐观锁使用创建一个user表插入数据版本号更新总结前言乐观锁,顾名