zoukankan      html  css  js  c++  java
  • Oracle 游标简介

    游标 游标的简介: 

    逐行处理查询结果,以编程的方式访问数据

    游标的类型:

    1,隐式游标:在 PL/SQL 程序中执行DML SQL 语句时自动创建隐式游标,名字固定叫sql。

    2,显式游标:显式游标用于处理返回多行的查询。

    3,REF 游标:REF 游标用于处理运行时才能确定的动态 SQL 查询的结果

    隐式游标:


    q在PL/SQL中使用DML语句时自动创建隐式游标 q隐式游标自动声明、打开和关闭,其名为 SQL q通过检查隐式游标的属性可以获得最近执行的DML 语句的信息 q隐式游标的属性有: q%FOUND – SQL 语句影响了一行或多行时为 TRUE q%NOTFOUND – SQL 语句没有影响任何行时为TRUE q%ROWCOUNT – SQL 语句影响的行数 q%ISOPEN - 游标是否打开,始终为FALSE

    begin
      update student s set s.sage = s.sage + 10 ;
      if sql %FOUND   then
        dbms_output.put_line('这次更新了' || sql% rowcount );
        else
          dbms_output.put_line ('一行也没有更新' );
          end if;
          end;

    在select中有两个中比较常见的异常: 1. NO_DATA_FOUND 2. TOO_MANY_ROWS

    SQL> declare
      2  sname1 student.sname%TYPE;
      3  begin
      4    select sname into sname1 from student;
      5    if sql%found then
      6      dbms_output.put_line(sql%rowcount);
      7    else
      8      dbms_output.put_line('没有找到数据');
      9      end if;
     10      exception
     11        when too_many_rows then
     12          dbms_output.put_line('查找的行记录多于1行');
     13         when no_data_found then
     14            dbms_output.put_line('未找到匹配的行');
     15       end;
     16  /
    查找的行记录多于1行
    PL/SQL procedure successfully completed
    


    显式游标:



    sqlserver与oracle的不同之处在于: 最后sqlserver会deallocate 丢弃游标,而oracle只有前面四步: 声明游标、打开游标、使用游标读取记录、关闭游标。
    显式游标的使用:

    ------------------------------------无参数游标-------------------------------
    declare
      sname varchar2( 20); --声明变量
      cursor student_cursor is select sname from student ; --声明游标
      begin
        open student_cursor;--打开游标
          fetch student_cursor into sname ;--让游标指针往下移动
        while student_cursor%found --判断游标指针是否指向某行记录
          loop--遍历
            dbms_output.put_line ('学生姓名' ||sname );
            fetch student_cursor into sname;
          end loop;
           close student_cursor;
          end;
          
    ------------------------------------有参数游标-------------------------------
    declare
    sname student.sname%type;
    sno student.sno%type;
    cursor student_cursor (input_sno number) is select s.sname, s.sno from student s where s.sno > input_sno; --声明带参数的游标
    begin
      sno := &请输入学号 ;--要求从客户端输入参数值,"&"相当于占位符;
      open student_cursor( sno); --打开游标,并且传递参数
      fetch student_cursor into sname, sno; --移动游标
      while student_cursor% found
        loop
          dbms_output.put_line ('学号为:' ||sno ||'姓名为:' ||sname );
          fetch student_cursor into sname,sno;
          end loop;
           close student_cursor;
          end;
    ------------------------------------循环游标-------------------------------   
    -- Created on 18-1月-15 by 永文
    declare
    stu1 student%rowtype ;--这里也不需要定义变量来接收fetch到的值
    cursor student_cursor is select * from student ;
    begin
     open student_cursor; --这里不需要开启游标
      for stu1 in student_cursor
        loop
          dbms_output.put_line ('学生学号:' ||stu1.sno ||'学生姓名:' ||stu1.sname );
          fetch student_cursor into stu1;--也不需要fetch了
          end loop;
        close student_cursor;  --这里也不需要关闭游标
          end;
          
    ------------------------------------使用游标更新行-------------------------------  
      declare
      stu1 student%rowtype ;
      cursor student_cursor is select * from student s where s.sno in (2 ,3 ) for update;--创建更新游标
      begin
       open student_cursor;
       fetch student_cursor into stu1;--移动游标
       while student_cursor%found --遍历游标,判断是否指向某个值
         loop
           update student set sage = sage + 10 where current of student_cursor;--通过游标中的信息更新数据
            fetch student_cursor into stu1;--移动游标
           end loop;
           close student_cursor;
           end;
     
      declare
      stu1 student%rowtype ;
      cursor student_cursor is select * from student s where s.sno in (2 ,3 ) for update;--创建更新游标
      begin
       open student_cursor;
      -- fetch student_cursor into stu1;--移动游标
      -- while student_cursor%found--遍历游标,判断是否指向某个值
         loop
             fetch student_cursor into stu1 ;--移动游标
             exit when student_cursor %notfound ;
           update student set sage = sage + 10 where current of student_cursor;--通过游标中的信息更新数据
           end loop;
           close student_cursor;
           end;
    ------------------------------------使用fetch ... bulk collect into-------------------------------  
    declare
      cursor   my_cursor is select ename from emp where deptno= 10; --声明游标
      type   ename_table_type is table of varchar2 (10 );--定义一种表类型,表中的属性列为varchar2类型
      ename_table  ename_table_type;--通过上面定义的类型来定义变量
    begin
      open   my_cursor; --打开游标
      fetch my_cursor bulk collect into   ename_table; --移动游标
      for   i in 1 ..ename_table.count  loop
         dbms_output.put_line(ename_table(i));
      end   loop ;
      close my_cursor;
    end;
     
     
    -----------------------------------显示游标题目--------------------------------------
     
    SQL > select * from student ;
            XH XM
    ---------- ----------
             1 A
             2 B
             3 C
             4 D
     
    SQL > select * from address ;
            XH ZZ
    ---------- ----------
             2 郑州
             1 开封
             3 洛阳
             4 新乡
             
    完成的任务 :给表student添加一列zz ,是varchar2 (10 )类型;
    再从address中,将zz字段的数值取出来,对应的插入到
    student新增的zz列中。
    即:得到的结果:student表中,是:
              XH XM         ZZ
             -- ---------- ------
              1 A          开封
              2 B          郑州
              3 C          洛阳
              4 D          新乡
     
     
    declare
    stu1 student %rowtype ;
    add1 address %rowtype ;
    cursor student_cursor is select * from student for update;--声明更新游标
    cursor address_cursor is select * from address ;--声明游标
    begin
      open student_cursor ;--打开游标
      fetch student_cursor into stu1;--移动游标
      while student_cursor% found--判断游标是否指向某条记录
        loop
          open address_cursor ;--打开另外一个游标
          fetch address_cursor into add1 ;--移动游标
          while address_cursor %found--判断游标是否指向某条记录
            loop
              if add1.xh = stu1.xh then--判断两个游标所指向的记录中xh的值是否相等
                update student s set s.zz = add1.zz where current of student_cursor;--假如相等就更新游标所指向的记录值
                end if;
                fetch address_cursor into add1 ;--移动游标
                end loop;
                close address_cursor ;--关闭游标
                fetch student_cursor into stu1 ;--移动游标
                end loop;
                close student_cursor ;--关闭游标
                end;

    REF游标也叫动态游标:


    qREF 游标和游标变量用于处理运行时动态执行的 SQL 查询 q创建游标变量需要两个步骤: q声明 REF 游标类型 q声明 REF 游标类型的变量 q用于声明 REF 游标类型的语法为:

    
    

    TYPE <ref_cursor_name> IS REF CURSOR

    
    

    [RETURN <return_type>];



    --
    ---------------------------------ref游标--------------------------------- declare type ref_cursor is ref cursor; --声明一个ref游标类型 tab_cursor ref_cursor ;--声明一个ref游标 sname student.xm %type ; sno student.xh %type ; tab_name varchar2 (20 ); begin tab_name := '&tab_name'; --接收客户输入的表明 if tab_name = 'student' then open tab_cursor for select xh ,xm from student ; --打开ref游标 fetch tab_cursor into sno ,sname ;--移动游标 while tab_cursor %found loop dbms_output.put_line ('学号:' ||sno ||'姓名:' ||sname ); fetch tab_cursor into sno ,sname ; end loop; close tab_cursor ; else dbms_output.put_line ('没有找到你想要找的表数据信息' ); end if; end; -----------------------------------ref游标题目--------------------------------- SQL > select * from student ; XH KC ---------- ---------- 1 语文 1 数学 1 英语 1 历史 2 语文 2 数学 2 英语 3 语文 3 英语 9 rows selected SQL > 完成的任务 : 生成student2表 (xh number, kc varchar2 (50 )); 对应于每一个学生,求出他的总的选课记录,把每个学生的选课记录插入到student2表中。 即,student2中的结果如下: XH KC --- ------------------------------------------- 1 语文数学英语历史 2 语文数学英语 3 语文英语 create table student2 (xh number, kc varchar2 (50 )); declare kcs varchar2 (50 ); kc varchar2 (50 ); type ref_cursor is ref cursor; --声明一个ref游标类型 stu_cursor ref_cursor ;--定义一个ref游标类型的变量 type tab_type is table of number; --声明一个table类型 tab_xh tab_type ;--定义一个表类型的变量 cursor cursor_xh is select distinct( xh) from student; --声明一个游标 begin open cursor_xh; --打开游标 fetch cursor_xh bulk collect into tab_xh; --提取数据到表中 for i in 1 .. tab_xh.count loop kcs :='' ; open stu_cursor for select kc from student s where s.xh = tab_xh(i ); --打开ref游标 fetch stu_cursor into kc ; --移动游标 while stu_cursor %found loop kcs := kc ||kcs ; --连接字符串使用||而不是+ fetch stu_cursor into kc ; --移动游标 end loop; insert into student2 (xh , kc ) values( i, kcs); close stu_cursor ; end loop; close cursor_xh ; end;
  • 相关阅读:
    HBASE列族不能太多的真相 (一个table有几个列族就有几个 Store)
    Linux虚拟机添加新硬盘的全程图解
    Servlet 单例多线程
    MapReduce类型与格式(输入与输出)
    hbase集群的启动,注意几个问题
    spring 的IoC的个人理解
    深入Java核心 Java中多态的实现机制(1)
    spring mvc 请求转发和重定向(转)
    XML中<beans>中属性概述
    hadoop+javaWeb的开发中遇到包冲突问题(java.lang.VerifyError)
  • 原文地址:https://www.cnblogs.com/ChineseIntelligentLanguage/p/6428159.html
Copyright © 2011-2022 走看看