游标:显式游标和隐式游标,系统游标

本文深入讲解了SQL中游标的使用方法,包括隐式游标与显式游标的区别及应用场景,通过实例演示如何进行数据查询、提取及更新操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

begin
    语句块中,可以直接编写增删改操作的sql语句;
    insert into stu values(1001,'zhangsan');
    update stu set stuname='zs' where stuid=1001;
    delete from stu where stuid=1001;
    commit;
    在语句块中,如果需要查询(select),不能直接编写查询语句
    如果一定要写查询,必须接收查询结果;接收查询结果,主要依靠游标来接收
end;

显示游标和隐式游标
set serveroutput on;
隐式游标:
declare
    v_no emp.empno%type;--后面用来指定v_no的类型,表示与emp表的empno字段的类型一致;
    v_name emp.ename%type;
    v_sal emp.sal%type;
begin
    select empno,ename,sal into v_no,v_name,v_sal from emp;
    dbms_output.put_line('v_no:'||v_no);
    dbms_output.put_line('v_name:'||v_name);
    dbms_output.put_line('v_sal:'||v_sal);
exception
    when TOO_MANY_ROWS then dbms_output.put_line('返回了太多行了');
end;

上面,接收了一个或有限的几个字段值,如果一张表里有很多字段,而且都要查询的时候?
例子:查询整行:
declare
    empinfo emp%rowtype;--使用变量empinfo来接收emp的一行数据
begin
    select * into empinfo from emp where empno=7369;
    dbms_output.put_line('empno:'||empinfo.empno);
    dbms_output.put_line('ename:'||empinfo.ename);
    dbms_output.put_line('sal:'||empinfo.sal);
end;
使用 rowtype指定类型,并接收数据的时候,必须接收一行完整的数据

上述所有例子中,都只能接收一行以内的数据,如果查询返回了多行呢?--》显式游标

*****************************************************************************************
显式游标
显式游标的使用,分四个步骤:
1.申明游标
2.打开游标
3.提取游标
4.关闭游标

例子1:根据员工编号,查询员工的工资
declare
    v_no emp.empno%type:=7369;
    cursor empinfo is select sal from emp where empno=v_no;--申明游标
    v_sal emp.sal%type;
begin
    open empinfo;--打开游标
    fetch empinfo into v_sal;--提取游标
    dbms_output.put_line('v_sal:'||v_sal);
    close empinfo;--关闭游标
end;

例子2:查询指定员工的名字和工资,同时查询该员工所在部门的名字
declare
    v_no emp.empno%type:=7369;
    cursor empinfo is select e.ename,e.sal,d.dname from emp e,dept d where e.deptno=d.deptno and e.empno=v_no;--申明游标
    v_sal emp.sal%type;
    v_name emp.ename%type;
    v_dept_name dept.dname%type;
begin
    open empinfo;--打开游标
    fetch empinfo into v_name,v_sal,v_dept_name;--提取游标
    dbms_output.put_line('v_name:'||v_name);
    dbms_output.put_line('v_sal:'||v_sal);
    dbms_output.put_line('v_dept_name:'||v_dept_name);
    close empinfo;--关闭游标
end;

例子3:根据员工编号,查询员工所有信息
declare
    v_no emp.empno%type:=7369;
    cursor v_e is select * from emp where empno=v_no;
    v_emp emp%rowtype;
begin
    open v_e;
    fetch v_e into v_emp;
    dbms_output.put_line('empno:'||v_emp.empno);
    dbms_output.put_line('ename:'||v_emp.ename);
    dbms_output.put_line('sal:'||v_emp.sal);
    dbms_output.put_line('hiredate:'||v_emp.hiredate);
    close v_e;
end;

例子4:查询所有员工信息(多行)
declare
    cursor allemp is select * from emp;
    empinfo emp%rowtype;
begin
    open allemp;
    loop
        fetch allemp into empinfo;
        if allemp%notfound then exit;end if;
        dbms_output.put_line('empno:'||empinfo.empno||',行数:'||allemp%rowcount);
        
        --dbms_output.put_line('ename:'||empinfo.ename);
        --dbms_output.put_line('sal:'||empinfo.sal);
        --dbms_output.put_line('hiredate:'||empinfo.hiredate);        
    end loop;
    if allemp%isopen then close allemp; end if;
end;

for也可以循环游标
DECLARE
    CURSOR allemp IS SELECT * FROM emp;    
BEGIN
    FOR I IN allemp LOOP
        dbms_output.put_line('empno:'||I.empno||',ename:'||I.ename||',行数:'||allemp%rowcount);    
    END LOOP;      
end;

--通过游标修改数据
declare
   cursor userinfo is select * from sporter where sporterid=1001 for update;
   v_name varchar2(50);
begin
   for i in userinfo loop
     v_name :=i.sportername;
     update sporter set sportername='王五' where current of userinfo;
     dbms_output.put_line('用户信息:'||i.sporterid||'-------'||i.sportername);
   end loop;
   commit;
end;

------------------------------------------------------------------------------------------------------------------------

隐式游标和显式游标区别:
隐式:into,接收的结果只能是一行以内的数据;
显式:可以接收一个数据,多个数据,一行数据,多行数据;显式游标不再使用into;
    cursor,sys_refcursor
    cursor只能在存储过程内部使用,超出存储过程范围外,cursor的存储空间会被释放;
    sys_refcursor系统游标的存储空间,是独立于具体的某个存储过程以外的,所以某个存储过程的执行结束(存储过程执行的空间会被释放),不会影响系统游标的数据;
---------------------------------------------------------------
create procedure xxxx(
    zz out cursor
)is
    cursor zz is select * from biao;
begin
    open zz;
    loop
        fetch zz into 变量1,变量2....
        if zz%notfound then exit;end if;
        使用变量中的数据;
    end loop;
    close zz;
end;
--------------------------------------------------------------        
create procedure xxxx(
    yy  out sys_refcursor
)is
begin
    open yy for select * from 表;
end;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

好好羊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值