oracle-数据库05

本文介绍了数据库中的游标概念,将其比喻为单步调试中的断点,用于逐行处理数据。文章通过示例详细解释了静态游标的工作原理,包括声明内存变量、定义游标、打开、关闭游标以及使用循环进行数据操作。此外,提到了隐式游标在单条SQL语句中的应用,并预告了动态游标(RefCursor)的内容。
摘要由CSDN通过智能技术生成

对于编程语言都会有成块的语句用来一次性进行一个较复杂的操作,咱们数据库也有,接下来几篇将会提到游标、存储过程、以及触发器。

本篇讲解游标。

一、介绍

怎么说呢,游标就像在进行单步断点调试中的那个断点,程序进行到哪一步,断点就停在哪一行(可能描述不准确,仅用来解释游标),游标就是数据操作到哪一行就指向哪一行

 二、举例

游标可能对我来说比较陌生,所以我用例子引用的方法来给自己一个大致的样子和了解。(该例为静态显示游标)

--将persons表中某一城市的学生姓名、年龄取出并存入c_p表中
declare
    v_city Persons.city %type := &p_city;
    v_name Persons.name %type;
    v_age Persons.age %type;
    cursor c is select name,age from Persons
        where city = v_city;
begin
    open c;
        loop
            fetch c into v_name,v_age;
            exit when c %notfound;
            insert into c_p(name,age) values(v_name,v_age);
        end loop;
    close c;
    commit;
end;

看缩进,有两部分 declarebegin-enddeclare中定义了内存变量、游标变量begin-end中有open 游标loop-end loopclose 游标commit,在这其中loop-end loop中就是具体操作。

了解后,我们来详细对游标分类说明。

 三、游标分类说明

1、静态

静态是指在编译阶段,数据的结果集已经确定 

(1)显示Cursor

主要是用于一条select多条结果的情况

a.结构:declare + begin-(open-(操作)-close)-end

  • 定义:

(内存变量)

v_name1 char;
--类型为char
v_name2 table.name %type;   
--类型为table表中name属性的类型

内存变量有变量名、属性即可

(游标变量)

cursor c_name [可加参数] is
    select ……;

这样使得游标select出来的结果建立了关联

  • 打开游标:

在这里电脑内部帮我们完成了很多事:

  1. 执行游标对应的select语句
  2. 将查询结果放入工作区
  3. 将游标指针指向工作区首部
open c_name(v1,v2); --定义有参数时加上参数值
  • 取值:

操作:

  1. 将游标对应的数据取出
  2. 放入到指定的输出变量中
  3. 游标自动下移一行
fetch c_name into v1,v2;
--取出数据    放入  指定输出变量

或

fetch c_name into pl/sql_record;
--使用记录变量

记录变量定义:(可跳过)

 含义:类似结构体变量,其类型为组合类型

re_name c_name %rowtype;  --以 c_name游标中的属性类型 为一个组合类型

或

re_name t_name %rowtype;  --以 t_name表中的属性类型 为一个组合类型

  • 关闭游标:
close c_name;
  •  游标属性

可以在操作中使用,来判断游标位置和状态

c_name % isopen     --返回布尔型,判断游标是否打开

c_name % notfound   --返回布尔型,判断最近一次fetch有无结果,无结果为true

c_name % found      --与notfound相对

c_name % rowcount   --返回数字型,返回当前为止的记录数

b.整体结构:

declare
    v_name2 char; 
    v_name2 table.name %type; 
    cursor c_name is
    select ……;
begin
    open c_name(v1,v2);
    fetch c_name into v1,v2;
    close c_name;
end;

c.回看举例:

--将persons表中某一城市的学生姓名、年龄取出并存入c_p表中
declare
    v_city Persons.city %type := &p_city;
    v_name Persons.name %type;
    v_age Persons.age %type;
    cursor c is select name,age from Persons
        where city = v_city;
begin
    open c;
        loop
            fetch c into v_name,v_age;
            exit when c %notfound;
            insert into c_p(name,age) values(v_name,v_age);
        end loop;
    close c;
    commit;
end;
  •  loop-end loop:这是一个循环,将fetch放在循环内可依次获得缓冲区的每一行

对于循环c语言学过for(int i=0;i<n;i++),需要确定循环起末以及跨度,例子中条件为无跨度条件为fetch自动下移条件用exit when 定义 c % notfound(注意循环中语句的位置)

 while …… loop-end loop(替代loop-end loop)

fetch c into v_name,v_age;
while c % found loop
    insert into c_p(name,age) values(v_name,v_age);
    fetch c into v_name,v_age;
end loop;

 for …… loop-end loop(替代begin-end中的内容)

for re_name in c loop
    insert into c_p(name,age)
        values(re_name.name,re_name.age);
end loop;

 这里适用于用记录变量来遍历,这里的记录变量为系统隐式定义无需自行定义,这里的格式就很像Pythonfor …… in……

  •  := &p_city:这是通过人机交互的方式给v_city赋值,简单来说就是程序运行时会有弹窗给你输入数值来赋值

这里p_city仅仅是个名称,可变化但不要与其他名称重复 

  • commit:是一个结束当前事务的操作,目前以我的能力还不太能用到它(可不用)
(2)隐式Cursor

主要用于一条select仅有一条结果的情况

怎么说呢,隐式游标就是你不需要手动去定义游标,系统会自动生成一个游标来辅助你

其中insert、delete、select、update语句都有隐式游标存在

举例:

--清空s表中的数据并输出删了多少行
begin  
    delete from s;  
    --输出 
    dbms_output.put_line(sql%rowcount||'行已清除'); 
    commit;   
end;

结果:

  • delete:这里隐含了一个游标
  • dbms_output.put_line:这是输出语句
  • sql%rowcount%rowcount就是游标属性,sql为隐含游标的统一名称

2、动态

动态与静态相对,即编译阶段还不能确定结果集。

Ref Cursor

举例:

declare
c1 sys_refcursor;    --游标定义
v1 varchar2(20);
v2 number;
begin
  --打开并定义游标所查的结果集
  open c1  for select ename from emp;
  loop
    fetch c1 into v1;
    exit when c1%notfound;
    dbms_output.put_line(v1);
  end loop;
  close c1;
 open c1 for select loc from dept;
 loop
   fetch c1 into v1;
    exit when c1%notfound;
    dbms_output.put_line(v1);
  end loop;
  close c1;
 open c1 for select count(1) from emp group by deptno;
 loop
   fetch c1 into v2;
   exit when c1%notfound;
    dbms_output.put_line(v2);
  end loop;
  close c1;
end;

未完待续

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值