PLSQL-游标
时间:2022-07-25
本文章向大家介绍PLSQL-游标,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
游标(Cursor):用来查询数据库,获取记录集合(结果集)的指针,可以让开发者一次访问一行结果集,在每条结果集上作操作。
- 游标可分为: 1.静态游标:分为显式(explicit)游标和隐式(implicit)游标。 2.REF游标(动态游标):是一种引用类型,类似于指针。
- 显式和隐式游标的区别: 尽量使用隐式游标,避免编写附加的游标控制代码(声明,打开,获取,关闭),也不需要声明变量来保存从游标中获取的数据。
- REF游标和静态游标的区别 1)静态游标不能返回到客户端。ref游标能够被返回到客户端,是从Oracle的存储过程返回结果集的方式。 2)不能在包说明或包体中的过程或函数之外定义ref游标。只能在定义ref游标的过程中处理它,或返回到客户端应用程序。 3)ref游标可以从子例程传递到子例程,而游标则不能。 为了共享静态游标,必须在包说明或包体中把它定义为全局游标。 4)使用静态游标--通过静态SQL(但不用ref游标)--比使用ref游标效率高,
静态游标
显式游标
- 显式游标的使用方法: 第一步:声明游标 第二步:打开游标 第三步:使用游标进行循环操作 第四步:关闭游标
create or replace procedure TEST is
cursor c1(inname in varchar2) is
select tname from tab where tname like inname;
pname varchar2(32);
begin
open c1('T%');
loop
fetch c1 into pname;
exit when c1%notfound;
dbms_output.put_line(pname);
end loop;
close c1;
end TEST;
DML隐式游标
- 在PL/SQL中使用DML语言,使用ORACLE提供的名为“SQL”的隐示游标。
declare
begin
update departments set department_name = department_name;
dbms_output.put_line('update ' || sql%rowcount || ' records');
end;
CURSOR FOR IN LOOP隐式游标
//例子1:无参数,使用循环,无须打开关闭游标
create or replace procedure TEST is
cursor c1 is select tname from tab;
begin
for rr in c1 loop
dbms_output.put_line(rr.tname);
end loop;
end TEST;
//例子2:有参数,使用循环,无须打开关闭游标
create or replace procedure TEST is
cursor c1(inname in varchar2) is select tname from tab where tname like inname;
begin
for rr in c1('T%') loop
dbms_output.put_line(rr.tname);
end loop;
end TEST;
游标的常用属性
- %FOUND:变量最后从游标中获取记录的时候,在结果集中找到了记录。
- %NOTFOUND:变量最后从游标中获取记录的时候,在结果集中没有找到记录。
- %ROWCOUNT:当前时刻已经从游标中获取的记录数量。
- %ISOPEN:是否打开。
declare /* /* 定义静态游标 */ */
Cursor emps is
Select * from employees where rownum < 6 order by 1;
emp employees%rowtype;
row number := 1;
begin
Open emps; /* ´打开静态游标 */
fetch emps into emp; /* 读取游标当前行 */
loop
if emps%found then
dbms_output.put_line('Looping over record ' || row || ' of ' || emps%rowcount);
fetch emps into emp;
row := row + 1;
elsif emps%notfound then
exit;
end if;
End loop;
If emps%isopen then
close emps; /* 关闭游标 */
End if;
End;
游标的更新与删除
- UPDATE或DELETE语句中的WHERE CURRENT OF子串专门处理要执行UPDATE或DELETE操作的表中取出的最近的数据。要使用这个方法,在声明游标时必须使用FOR UPDATE子串.
- 当对话使用FOR UPDATE子串打开一个游标时,所有返回集中的数据行都将处于行级(ROW-LEVEL)独占式锁定,其他对象只能查询这些数据行,不能进行UPDATE、DELETE或SELECT...FOR UPDATE操作。
- 在多表查询中,使用OF子句来锁定特定的表,如果忽略了OF子句,那么所有表中选择的数据行都将被锁定。如果这些数据行已经被其他会话锁定,那么正常情况下ORACLE将等待,直到数据行解锁。
- 在UPDATE和DELETE中使用WHERE CURRENT OF子串的语法如下: WHERE{CURRENT OF cursor_name|search_condition}
create or replace procedure pc_SetVersionValid(PFlowsID in integer) is
Cursor c1 is
select * from wf_flows
where flowname in
(select flowname from wf_flows where flowsid = PFlowsID)
for update;
r c1%rowtype;
v integer;
begin
open c1;
fetch c1 into r;
while c1%found loop
if r.flowsid = PFlowsID then
v := 1;
else
v := 0;
end if;
UPDATE wf_flows SET isValid = v WHERE CURRENT OF c1;
fetch c1 into r;
end loop;
close c1;
commit;
end;
引用游标ref cursor
弱类型引用游标,就是不指定游标将要提取的数据行的类型
declare
type my_cur_type is ref cursor;
mycur my_cur_type;--声明引用游标变量
which varchar2(10);
deptrow dept%rowtype;
emprow emp%rowtype;
begin
which := '&请选择dept还是emp';
if (which = 'dept') then
open mycur for select * from dept; --引用游标可以动态sql
loop
fetch mycur into deptrow;
exit when (mycur%notfound);
dbms_output.put_line(deptrow.deptno || ' ' || deptrow.dname);
end loop;
elsif (which = 'emp') then
open mycur for select * from emp; --引用游标可以动态sql
loop
fetch mycur into emprow;
exit when (mycur%notfound);
dbms_output.put_line(emprow.empno || ' ' || emprow.ename);
end loop;
end if;
close mycur;
end;
强类型引用游标
- 就是指定游标将要提取的数据行的类型 ,只能是record或%rowtype类型.比如:return number是错的,return emp.ename%type也是错的
declare
type mycurtype is ref cursor return emp%rowtype;
mycur mycurtype;--声明变量
emprow emp%rowtype;
begin
open mycur for select * from emp;
loop
fetch mycur into emprow;
exit when mycur%notfound;
dbms_output.put_line(emprow.empno || ' ' || emprow.ename);
end loop;
close mycur;
end;
喜欢 (9)or分享 (0)
- [接口测试 - http.client篇] 17 http.client之入门级接口测试框架
- 评论JS插件~多说+畅言
- jQuery HTML5 Uploader
- 1022: [SHOI2008]小约翰的游戏John【Nim博弈,新生必做的水题】
- [接口测试 - http.client篇] 16 基于http.client之POM实战一下
- 数论部分第一节:素数与素性测试【详解】
- ProtoBuf 序列化工具组件
- C++STL vector简单使用练习1
- 小解Redis 系列
- 小侃 SQL加密和性能
- 接口测试 | 25 requests + pytest测试实例
- 接口测试 | 24 requests + unittest集成你的接口测试
- 接口测试 23 requests基础入门二
- 写让别人能读懂的代码+网页性能管理详解
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- React总结概括
- Spring Http Invoker
- Spring整合RMI
- Spring启用缓存
- 交通标识分类-TensorFlow实现
- Redis使用与操作k-v数据
- Spring集成Hadoop和Hbase
- JVM系列之:JIT中的Virtual Call接口
- 重新构建711的Android项目(二),架构的选择与实现
- Android的配置文件操作封装,摒弃SharedPreference操作配置漫天乱飞
- java实现PBOC的TLV格式解析,超简单的解析(全互联网最简单)
- 链表总计
- Spring整合MongoDb
- 正确使用Qt多线程
- Spring与hibernate与mybatis