游标的简介

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

游标的类型:

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
   ;
  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

DECLARE
   sname1   student.sname%TYPE;
BEGIN
   SELECT sname INTO sname1 FROM student;

   IF SQL%FOUND
   THEN
      DBMS_OUTPUT.put_line (SQL%ROWCOUNT);
   ELSE
      DBMS_OUTPUT.put_line ('没有找到数据');
   END IF;
EXCEPTION
   WHEN TOO_MANY_ROWS
   THEN
      DBMS_OUTPUT.put_line ('查找的行记录多于1行');
   WHEN NO_DATA_FOUND
   THEN
      DBMS_OUTPUT.put_line ('未找到匹配的行');
END;

二、显式游标:

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

------------------------------------无参数游标-------------------------------
DECLARE
   sname   );                                               --声明变量

   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;
------------------------------------循环游标-------------------------------

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
       , )
      FOR UPDATE;                                                     --创建更新游标
BEGIN
   OPEN student_cursor;

   FETCH student_cursor INTO stu1;                                      --移动游标

   WHILE student_cursor%FOUND                                 --遍历游标,判断是否指向某个值
   LOOP
      UPDATE student

       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
       , )
      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

       WHERE CURRENT OF student_cursor;                         --通过游标中的信息更新数据
   END LOOP;

   CLOSE student_cursor;
END;
------------------------------------使用fetch ... bulk collect into-------------------------------
DECLARE
   CURSOR my_cursor
   IS
      SELECT ename
        FROM emp
       ;                                               --声明游标

   TYPE ename_table_type ); --定义一种表类型,表中的属性列为varchar2类型

   ename_table   ename_table_type;                            --通过上面定义的类型来定义变量
BEGIN
   OPEN my_cursor;                                                      --打开游标

   FETCH my_cursor BULK COLLECT INTO ename_table;                       --移动游标

    .. ename_table.COUNT
   LOOP
      DBMS_OUTPUT.put_line (ename_table (i));
   END LOOP;

   CLOSE my_cursor;
END;
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  );
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
---------- ----------
          语文
          数学
          英语
          历史
          语文
          数学
          英语
          语文
          英语
 rows selected

SQL >
完成的任务 :
生成student2表 (xh  ));
对应于每一个学生,求出他的总的选课记录,把每个学生的选课记录插入到student2表中。
即,student2中的结果如下:
                      XH KC
                 --- -------------------------------------------
                        语文数学英语历史
                        语文数学英语
                        语文英语

 ));

declare
kcs  );
kc  );
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; --提取数据到表中
   .. 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;

Oracle中的游标的原理和使用详解的更多相关文章

  1. 【转】oracle中的游标的原理和使用详解

    游标 游标的简介: 逐行处理查询结果,以编程的方式访问数据 游标的类型: 1,隐式游标:在 PL/SQL 程序中执行DML SQL 语句时自动创建隐式游标,名字固定叫sql. 2,显式游标:显式游标用 ...

  2. oracle中的exists 和not exists 用法详解

    有两个简单例子,以说明 “exists”和“in”的效率问题 1) select * from T1 where exists(select 1 from T2 where T1.a=T2.a) ; ...

  3. oracle中的exists 和not exists 用法详解(转)

    有两个简单例子,以说明 “exists”和“in”的效率问题 1) select * from T1 where exists(select 1 from T2 where T1.a=T2.a) ; ...

  4. oracle中去掉回车换行空格的方法详解

    函数: 1.translate语法:TRANSLATE(char, from, to)用法:返回将出现在from中的每个字符替换为to中的相应字符以后的字符串.            若from比to ...

  5. oracle中检索结果汉字首字母排序详解

    今天写需求,要求将结果按照成本中心首字母排序,平且空放在最前面. 进入正题: 1.使用oracle自带的函数: 按照首字母排序:nlssort(xxx,'NLS_SORT=SCHINESE_PINYI ...

  6. oracle 中的游标

    oracle 中的游标 通俗易懂的sql代码直接上! --简单的游标使用滴呀 --使用FOR OBJ IN OBJS LOOP ......END LOOP; DECLARE CURSOR C_JOB ...

  7. Oracle中使用游标转换数据表中指定字段内容格式(拼音转数字)

    应用场景:将数据表TB_USER中字段NNDP的内容中为[sannanyinv]转换为[3男1女] 主要脚本:一个游标脚本+分割字符串函数+拼音转数字脚本 操作步骤如下: 1.创建类型 create ...

  8. Oracle中使用游标获取指定数据表的所有字段名对应的字符串

    操作步骤:打开PLSQL Developer后,直接执行下面的语句就可以出来 --Oracle中使用游标获取指定数据表的所有字段名对应的字符串 declare mytablename VARCHAR( ...

  9. Oracle中的SQL分页查询原理和方法详解

    Oracle中的SQL分页查询原理和方法详解 分析得不错! http://blog.csdn.net/anxpp/article/details/51534006

随机推荐

  1. iOS安全攻防之结构体保护使用

    Objective-C 代码很容易被 hook,因此需要对一些重要的业务逻辑进行保护,可以改用结构体的形式,把函数名隐藏在结构体里,以函数指针成员的形式存储.这样编译后只留了下地址,去掉了名字和参数表 ...

  2. Django初探——工程创建以及models数据库相关配置

    Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM.模型绑定.模板引擎.缓存.Session等诸多功能. ...

  3. python_day5--->递归函数,二分法查找

    li = [1, 5, 6, 7, 12, 22, 33, 44, 55, 66, 77, 88, 99, 111, 222, 333]def er(num,li): if len(li) ==0: ...

  4. MVC+Bootstrap+Drapper使用PagedList.Mvc支持多查询条件分页

    前几天做一个小小小项目,使用了MVC+Bootstrap,以前做分页都是异步加载Mvc部分视图的方式,因为这个是小项目,就随便一点.一般的列表页面,少不了有查询条件,下面分享下Drapper+Page ...

  5. 图解Git命令

    上面的四条命令在工作目录.暂存目录(也叫做索引)和仓库之间复制文件. ·git add files把当前文件放入暂存区域. ·git commit 给暂存区域生成快照并提交. ·git reset - ...

  6. Spring 依赖注入之从不会到稍微会一点儿

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  7. asp.net core 教程(四)-项目结构

    Asp.Net Core-项目结构 Asp.Net Core-项目结构 案例 在这一章,我们将讨论 ASP.NET Core项目在文件系统上的组成方式以及不同的文件和目录都是如何协同工作的. 让我们打 ...

  8. Python给小说做词云

    闲暇时间喜欢看小说,就想着给小说做词云,展示小说的主要内容.开发语言是Python,主要用到的库有wordcloud.jieba.scipy.代码很简单,首先用jieba.cut()函数做分词,生成以 ...

  9. jQuery.validate 的form校验

    jQuery验证框架 : 基本html代码: <script src="js/jquery-1.9.1.js"></script> <script s ...

  10. WCF学习——构建一个简单的WCF应用(二)

    我们接着上一篇文章进行讲解 http://www.cnblogs.com/songjianhui/p/7060698.html 一:客户端通过添加引用调用服务 WCF应用服务被成功寄宿后,WCF服务应 ...