ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 游标

游标

原创 Linux操作系统 作者:tsai_vogue 时间:2013-01-17 16:46:05 0 删除 编辑
游标
一.游标简介
  1.游标类似于编程语言中指针的概念.
  2.游标的分类
    游标的主要类型分别静态游标和动态游标,静态游标是常用的游标.
    静态游标又分为显示游标和隐示游标.

二.显示游标和隐式游标
(一)显示游标
1.声明显示游标
  (1)声明游标
  delcare cursor 游标名称 is 查询语句;
  eg. declare cursor cu_emp is
select empno,ename,sal from emp;
  (2)声明列变量
  <被声明变量> <表名>.<参照列>%type;
  eg. declare cursor cu_emp is
select empno,ename,sal from emp;
      
      emp_id emp.empno%type;
      emp_name emp.ename%type;
      emp_sal emp.sal%type;
  (3)声明行变量
  变量名 表名%rowtype;
  eg.  declare cursor cu_emp is
select * from emp;

       emph emp%rowtype;
2.使用显示游标
  (1)打开游标
  open 游标名称;
  (2)通过游标来捕获数据
  fetch 游标名称 into 变量;
3.游标使用方法
  (1)使用普通变量获取游标信息
  set serverout on;
  declare cursor cu_emp is select empno,ename,sal from emp;
  emp_id emp.empno%type;
  emp_name emp.ename%type;
  emp_sal emp.sal%type;
  begin
    open cu_emp;
    fetch cu_emp into emp_id,emp_name,emp_sal;
    while cu_emp%found loop
      dbms_output.put_line(emp_id||':'||emp_name||':'||emp_sal);
      fetch cu_emp into emp_id,emp_name,emp_sal;
    end loop;
  end;
  /
  (2)使用行类型变量来获取油表信息
  set serverout on;
  declare cursor cu_emp is select * from emp;
  emph emp%rowtype;
  begin
    open cu_emp;
    fetch cu_emp into emph;
    while cu_emp%found loop
      dbms_output.put_line(emph.ename||':'||emph.job||':'||emph.sal);
      fetch cu_emp into emph;
    end loop;
  end;
  /
  (3)为游标传递参数
  显示游标可以带有参数,参数的意义在于为获取记录集合制定搜寻条件
  declare cursor cu_emp(minSal in number,maxSal in number) is select * from emp
where sal>=minSal and sal<=maxSal;
  emph emp%rowtype;
  begin
    open cu_emp(2000,3000);
    fetch cu_emp into emph;
    while cu_emp%found loop
      dbms_output.put_line(emph.ename||':'||emph.job||':'||emph.sal);
      fetch cu_emp into emph;
    end loop;
    close cu_emp;
  end;
  /
4.游标总结
  (1)fetch命令可以捕获当前记录,并将指针移至下一条记录.游标位置下移才能获得新纪录,如果使用循环,但是未在循环中加入fetch命令,则游标总会处于首条记录,容易产生死循环.
  (2)在游标使用完毕后,应该使用close命令将其关闭,以防占用数据库资源.
5.游标属性
  (1)found
  当用户执行了fetch命令,oracle将更新游标的found属性,如果利用fetch命令成功捕获了记录,那么found将被置为真(true),否则为假(false)
  (2)notfound
  该属性是found属性的对立面,当fetch命令不能成功捕获记录时,将返回true,否则返回false
  (3)rowcount
  该属性每次执行fetch时进行更新,用于返回当前时刻已捕获的记录数
  (4)isopen
  该属性被open和close命令更新,用于判断游标是否处于打开状态.打开为真(true),否则为假(false)

(二)隐式游标
  隐式游标是相对于显式游标而言.
  显示游标:用户通过声明游标(declare),打开游标(open),使用游标(fetch),关闭游标(close)等步骤控制显式游标的生命周期.
  隐式游标则不允许用户声明和控制,仅限于使用.隐式游标包括两种:使用oracle预定义的名为SQL的隐式游标和使用cursor for loop来进行循环的隐式游标.
1.SQL隐式游标的使用
  SQL游标是oracle的内置游标,SQL游标与当前会话有关,当前会话的更新(update),删除操作都会影响到SQL隐式游标的属性.
  (1)查看SQL隐式游标的默认值
  begin
    if sql%isopen then
      dbms_output.put_line('sql游标已打开');
    else
      dbms_output.put_line('sql游标未打开');
    end if;
    dbms_output.put_line('游标捕获记录数'||sql%rowcount);
  end;
  /
  sql游标未打开
  游标捕获记录数
  
  由此可以,在没有进行任何操作时,游标SQL的状态为'未打开';游标SQL的捕获记录数为空.虽然无法获得SQL游标的有用信息,但是至少证明SQL游标是存在的.

  (2)查询语句对SQL隐式游标的影响
  declare emp_no number;
  begin
    select empno into emp_no from emp where empno=7934;
    if sql%isopen then
      dbms_output.put_line('sql游标已打开');
    else
      dbms_output.put_line('sql游标未打开');
    end if;
    dbms_output.put_line('游标捕获记录数'||sql%rowcount);
  end;
  /
  sql游标未打开
  游标捕获记录数1

  (3)更新语句对sql游标的影响
  begin
    update emp set empno=empno+1;
    if sql%isopen then
      dbms_output.put_line('sql游标已打开');
    else
      dbms_output.put_line('sql游标未打开');
    end if;
    dbms_output.put_line('游标捕获记录数'||sql%rowcount);
  end;
  /
  sql游标未打开
  游标捕获记录数10

  (4)SQL隐式游标的使用
  SQL游标最常使用的属性为found和rowcount
  在应用开发中,经常出现这种场景:一条数据传入数据库的记录,用户并不能确定该记录是否存在,如果存在需要对记录的各列进行更新,否则,需要插入该记录.
  begin
    update emp set ename='TQW' where empno='120';
    if sql%rowcount=0 then
      insert into emp(empno,ename) values('120','TWES');
    end if;
  end;
  /
  对于判断条件sql%rowcount=0 可以用sql%notfound代替

2.cursor for游标的使用
  利用cursor for游标可以像使用普通循环语句一样处理select语句获得的每一天记录
  for 游标变量 in (查询语句) loop
    DML操作
  end loop;

  eg. begin
      for emp in (select * from emp) loop
        dbms_output.put_line(emp.ename||'-'||emp.job||'-'||emp.sal);
      end loop;
      end;
      /
   
(三)显示游标和隐式游标总结
   显示游标和隐式游标都可实现对记录集和循环操作.显示游标需要用户遵循声明,打开,捕获记录,操作记录和关闭等步骤.隐式游标则无需如此繁琐的步骤,而更接近于其他编程语言中的for循环.
   虽然显示游标操作复杂,但使用上却更加灵活,例如,在打开游标时传递参数,可以创建更加灵活多样的游标.相对而言,隐式游标操作步骤简练,但用户不能进行人工干预,隐刺适用于简单的游标操作.

三.动态游标
1.动态游标简介
  动态游标是指,在游标声明时,不指定其查询定义,而是在游标打开时进行定义.
  动态游标又可以分为两类:强类型动态游标和弱类型动态游标.
2.强类型动态游标
  强类型动态游标是指,在游标使用之前,虽未指定游标的查询定义,但是游标的类型已确定.也就是说游标所代表的记录类型必须确定.
  type 游标类型 is ref cursor
    return 记录类型
  
  eg.
  declare
  type refDeptCur is ref cursor return dept%rowtype; --返回dept 行类型
  deptCur  refDeptCur;
  deptData dept%rowtype;
begin
  open deptCur for
    select * from dept;
      fetch deptCur
      into deptData;
  loop
    exit when deptCur%notfound;
    dbms_output.put_line(deptData.dname);
    fetch deptCur
      into deptData;
  end loop;
  close deptCur;
end;

3.弱类型动态游标
  弱类型动态游标虽然在查询上具有一定的灵活性,但所返回的记录类型是一定的,有时候在游标定义时,无法确定其记录类型,那么使用弱类型动态游标是一个较好的选择.
  type 游标类型 is ref cursor

  eg.
  declare    
  type refEmpCur is ref cursor; --定义动态游标    
  empCur  refEmpCur; --声明变量为refEmpCur游标变量    
  empData emp%rowtype; --声明empData为emp表的行类型    
begin    
  open empCur for        --打开游标存储emp表数据    
    select * from emp;    
    
  loop    
    exit when empCur%notfound;    
    fetch empCur    
      into empData;    
    dbms_output.put_line('编号:' || empData.empno || ' 姓名:' || empData.ename);    
  end loop;    
  close empCur;    
end;    

四.游标小结
  最常用的是显示静态游标,用户可以手动控制显示游标的生命周期.
  隐式游标适用于对于简单查询进行处理的场合.
  静态游标总是在声明游标时,指定游标的查询定义,而动态游标则允许游标的查询定义在打开时指定,弱类型动态游标则进一步放宽限制--可以利用同一游标来获得不同数据结构中的记录.

  [静态游标]
      ↓ --声明时不指定查询定义
  [强类型动态游标]
      ↓ --声明时不指定返回类型
  [弱类型动态游标]

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/26918004/viewspace-752825/ ,如需转载,请注明出处,否则将追究法律责任。

上一篇: connect by的应用
下一篇: 没有了~
请登录后发表评论 登录
全部评论

注册时间:2012-12-19

  • 博文量
    10
  • 访问量
    13110