设为首页 收藏本站
查看: 2051|回复: 0

[经验分享] oracle 游标以及游标变量(1)

[复制链接]

尚未签到

发表于 2016-8-4 09:37:04 | 显示全部楼层 |阅读模式
  
ORACLE 游标
一. PL/SQL 是用游标来管理 SQL 的 SELECT 语句的 . 游标是为了处理这些语句而分配的一大块内存 . 它提供了对一个结果集进行逐行处理的能力 , 可看作是一种特殊的指针 . 它与某个查询结果集相关联 , 可以指向结果集的任意位置 , 以便对指定位置的数据进行处理 . 使用它可以在查询数据的同时对数据进行处理 .
二. 游标的分类 : 静态游标和动态游标
   1. 在说明游标分类之前, 先说明一下PL/SQL 的两个操作, 游标属性, 变量属性
SET SERVEROUTPUT ON ;-- 此语句用于开启打印输出功能
DMBS_OUTPUT.PUT_LINE();-- 打印输出并换行.
%FOUND: 判断当前游标是否指向有效的一条行记录. 是则返回TRUE, 否则返回FALSE
%NOTFOUND: 与%FOUND 恰好相反.
%ISOPEN: 判断游标是否打开, 打开则返回TRUE, 否则返回FALSE.
%ROWCOUNT: 判断当前游标在所指向的结果集中提取的行数. 并非所有总记录数
%TYPE: 声明变量的类型与表中的某列的数据类型完全一致.%TYPE 声明有两个好处: 一是你不必知道某列的确切数据类型二是当某列的数据类型改变时不用修改变量的数据类型.
%ROWTYPE: 声明变量的数据类型与表中的行记录数据类型一致. 对于自定义的记录, 则必须声明自己的域.
  2. 静态游标:
静态游标又可以分为两类:
1) 隐式游标
隐式游标的特点:
- 隐式游标是由PL/SQL 来管理的, 即不需要声明游标语句, 也不需要OPEN,FETCH,CLOSE 操作
- 隐式游标中必须要有select cur_name into [ 变量名或其他数据类型]. 此句完成OPEN,FETCH,CLOSE 操作.
- 隐式游标只能返回一行记录, 如果无符合条件的记录将会出现NO_DATA_FOUND 异常. 如果出现多条记录将出现TOO_MANY_ROWS 异常.
- 隐式游标只能用SQL% 判断其游标属性
- 对于任何位置使用SQL%ISOPEN 结果都是FALSE, 隐式游标由PL/SQL 管理
- 对于在隐式游标位置前使用SQL%FOUND 或SQL%NOTFOUND, SQL%ROWCOUNT 结果值是NULL( 不确定值)
示例表:
表名:test
字段名
数据类型
可否为空
id( 序号)
number
N
name( 姓名)
varchar2(20)
N
zym( 专业名)
varchar(40)
Y
cj( 成绩)
number
Y
logdate( 记录日期)
date
Y
EG1: 验证隐式游标的特性
  set serveroutput on;-- 开启输出
declare
  no test.id%type;-- 声明变量no 的数据类型同test 表的id 列一致
  ename test.name%type;
  begin
  if sql%isopen then         -- 判断游标是否打开
  dbms_output.put_line(' cursor is openning');
  else
  dbms_output.put_line('cursor is closed');
  end if;
if sql%notfound then – 判断游标是否指向有效的行
  dbms_output.put_line('no value');
  else
  dbms_output.put_line(no||' '||ename);
  end if;
dbms_output.put_line(sql%rowcount);
dbms_output.put_line('---------------');
 
  select id ,name into no ,ename from test where cj=90;-- 隐式游标必-- 须使用INTO
  dbms_output.put_line(sql%rowcount);
  if sql%isopen then
  dbms_output.put_line(' cursor is openning');
  else
  dbms_output.put_line('cursor is closed');
  end if;
  if sql%notfound then
  dbms_output.put_line('no value');
  else
  dbms_output.put_line(no||' '||ename);
  end if;
  exception
  when no_data_found then
     dbms_output.put_line('no value');
when too_many_rows then
      dbms_output.put_line('too many rows');
  end;
执行结果为:
cursor is closed
--------------------
1
cursor is closed
1001 qbnajj
去掉where 条件时的结果:
cursor is closed
--------------------
too many rows
EG2: 使用%ROWTYPE
declare
  rowtype test%rowtype;
  begin
  select * into rowtype from test where cj=90;
  dbms_output.put_line(rowtype.name||' '||rowtype.cj);
  exception
  when no_data_found then
     dbms_output.put_line('no value');
  when too_many_rows then
      dbms_output.put_line('too many rows');
  end;
执行结果:
qbnajj 90
EG3: 自定义RECORD 数据类型
declare
 
  type r_type is record(name test.name%type ,cj test.cj%type);
  re_type r_type;
  begin
  select name,cj into re_type from test where cj=90;
  dbms_output.put_line(re_type.name||' '||re_type.cj);
  exception
  when no_data_found then
     dbms_output.put_line('no value');
  when too_many_rows then
      dbms_output.put_line('too many rows');
  end;
/
执行结果:
qbnajj 90
2) 显示游标
声明语法:
DECLARE
CURSOR cur_name( 参数名 数据类型) is select_satatements ;-- 游标名后-- 可带参数
BEGIN
OPEN cur_name;
FETCH cur_name into [ 变量或者其他数据类型];
-- 可用循环语句迭代输出游标所指向的结果集.
CLOSE cur_name;
END;
显示游标特性:
- 显示游标由用户定义, 并由用户来管理游标, 可返回多行记录.
- 通常使用显示游标需要遵守以下规则
   声明游标 -> 打开游标 -> 读取数据 -> 关闭游标
    但由于FOR IN LOOP 语句包含OPEN,FETCH,CLOSE 操作所以不在此例.
  - 查看游标属性时, 使用cur_name%.
EG:PL/SQL 演示
declare
  no test.id%type;
  ename test.name%type;
  cjs test.cj%type;
  cursor test_cur is
  select id,name from test where cj>=cjs;-- 可通过PL/SQL 绑定变量输-- 入值(&cjs)
  begin
  cjs:=50;
  for t_cur in test_cur
  loop
  no:=t_cur.id;
  ename:=t_cur.name;
  dbms_output.put_line(no||' '||ename);
  end loop;
  end;
执行结果:
chenjunhua 80
qbnajj 90
cjh 52
EG2: 利用带参数的存储过程演示
create or replace procedure test_proce(cjs in test.cj%type)
  as
  no test.id%type;
  ename test.name%type;
  cursor test_cur is
  select id,name from test where cj>=cjs;
  begin
  open test_cur;
  fetch test_cur into no,ename;
  while test_cur%found
  loop
  dbms_output.put_line(no||' '||ename);
  fetch test_cur into no,ename;-- 将游标指向下条记录, 否则为死循环.
  end loop;
  close test_cur;
  end test_proce;
  exec test_proce(50);
执行结果:
chenjunhua 80
qbnajj 90
cjh 52
EG3: 带参数的游标与上面的类似

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-252594-1-1.html 上篇帖子: Oracle分区键与分区本地索引 下篇帖子: oracle中常用函数大全(转)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表