zoukankan      html  css  js  c++  java
  • 六、Oracle SQL(游标&RECORD&存过、游标、RECORD整合)

    8. 游标

    8.1 简介

    8.1.1 定义

    实质上是数据集,类似数组一样,把查询的数据集存储在内存当中。
    使用时可以通过游标指向其中一条记录,也可以通过循环游标达到循环数据集的目的。

    8.1.2 游标的种类

    • 显式游标:使用之前必须得先声明定义,一般是对查询语句的结果进行定义游标。
      可以通过游标循环获取结果集内的记录,也可以根据业务需求跳出循环结束游标的获取。
      循环完成后,可以通过关闭游标,结果集就不能再获取了。全部操作完全由开发者自己编写完成,自己控制。

    • 隐式游标:指的是PL/SQL自己管理的游标,开发者不能自己控制操作,只能获得它的属性信息。

    8.2 显式游标

    显式游标在实际开发中经常使用到,可以丰富PL/SQL的开发程序的编写,实现一些循环类的复杂业务。游标的使用步骤如下:

    --1.声明游标:
      声明游标指的是给游标命名并给游标关联一个查询结果集
    cursor 游标名
    is 查询语句
    
    --2.打开游标:
      初始化游标指针
      PS:游标一旦打开后,游标对应的结果集就是静态不会再变了,不管查询的表的基础数据发生了变化。
    open 游标名;
    
    --3.读取游标中数据:
      通过fetch into语句完成,把当前游标指针指向的数据行读取到对应的变量中(声明的record变量)。
      PS:游标读取一般和循环LOOP一起使用,用于循环获取数据集中的记录。
    fetch 游标名 into 声明的record变量
    
    --4、关闭游标:
      关闭后,该游标关联的结果集就释放了,不能够再操作了
      PS:游标使用完,一定要关闭游标释放资源。
    close 游标名;
    

    8.2.1显式游标的属性

    我们利用显式游标的属性值来获取游标所处的状态,然后对应做相应的处理,常用的属性有四个:

    • %NOTFOUND 表示游标获取数据的时候是否有数据提取出来,没有数据返回TRUE,有数据返回false,经常被用来判断游标是否全部循环完毕。

    • %FOUND 正好和%NOTFOUND相反,当游标提取数据值时有值,返回TRUE,否则返回FALSE。

    • %ISOPEN 用来判断游标是否打开。

    • %ROWCOUNT 表示当前游标FETCH INTO获取了多少行的记录值,用来做计数用的。

    例子:创建一个游标循环打印学生信息表中学生基本信息,代码如下:

    --定义游标
    declare cursor cur_xsjbxx
    is select * from stuinfo order by stuid;
      --定义记录变量  rowtype:用于接受一行数据
      ls_curinfo cur_xsjbxx%rowtype;
    begin
        --打开游标
      open cur_xsjbxx;
        --循环
      loop
            --获取记录值并写入计入变量
        fetch cur_xsjbxx into ls_curinfo;
            --当没有数据时不再获取(%NOTFOUND用来判断游标是否全部循环完毕。)
            exit when cur_xsjbxx%notfound;
            --PL/sql中输出信息(相当与java中的System.out.println())
        dbms_output.put_line('学号:' || ls_curinfo.stuid || ',姓名:' || ls_curinfo.stuname);
      end loop;
        --关闭游标
      close cur_xsjbxx;
    end;
    

    8.3 隐式游标

    • 隐式游标虽然不能像显式游标一样具有操作性,但是在实际开发过程当中还是经常使用到它的属性值。

    • 隐式游标主要是用在select语句或一些dml操作语句时,PL/SQL程序会自动打开隐式游标,这个隐式游标是不受开发者控制的。

    • oracle隐式游标没有像显式游标一样声明游标名,而是直接采用“SQL”或“sql”作为隐式游标的名称。

    • 显式游标表示的属性值都是对结果集行数的一些判断,而隐式游标对应的就是DML语句影响的行数。

    --隐式游标
    declare
      --只定义记录变量,没有声明游标(如果一个表有较多的列,使用%rowtype来定义一个表示表中一行记录的变量)
      ls_xsjbxx stuinfo%rowtype;
    begin
      --查询学生信息(select * into把整个表数据设置进定义的记录变量中,用变量来实现游标功能)
      select * into ls_xsjbxx from stuinfo t where t.stuid = 'SC201801001';
      if sql%found then
        dbms_output.put_line('学号:' || ls_xsjbxx.stuid || ',姓名:' || ls_xsjbxx.stuname);
      end if;
    
      --查询学生信息(不存在的学生)
      select * into ls_xsjbxx from stuinfo t where t.stuid = 'SC201901001';
      if sql%found then
        dbms_output.put_line('学号:' || ls_xsjbxx.stuid || ',姓名:' || ls_xsjbxx.stuname);
      end if;
    exception
      when no_data_found then
        dbms_output.put_line('该学生SC201901001不存在');
    end;
    

    9. RECORD(自定义结构)

    9.1 定义

    记录数据类型的一种,将几个相关的、分离的、基本数据类型的变量组成一个类似于整体表结构的对象,即RECORD复合数据类型。
    在使用记录数据类型变量时,需要在声明部分先定义记录的组成、记录的变量,然后在执行部分引用该记录变量本身或其中的成员。
    RECORD数据类型常用于存过与游标结合使用时,用于记录数据。

    9.2 格式

    /**
    格式:
    TYPE 名称(随便起)IS RECORD(
            列1名称  列1类型,
            列2名称  列2类型
    );
    */
    
     TYPE T_RECORD IS RECORD (
        GOODS_CODE  VARCHAR2(64),
        GOODS_NAME VARCHAR2(64),
        ORDER_NUM VARCHAR2(16),
        DIS_ORDER_NUM VARCHAR2(16),
        TOTAL_ORDER_NUM VARCHAR2(16),
    );
    

    10. 存过、游标、RECORD整合

    10.1 代码

    /*1.定义存过*/
    CREATE OR REPLACE
    PROCEDURE PRO_RE_USER_ORD_GOODS(
    --NOW_DATE格式:YYYYMMDD 如:20190801(此时统计的是2019年7月31日的数据)
    NOW_DATE IN VARCHAR2
    )
    IS
    
        /*2.定义变量 START*/
        --定义RECORD型记录类型;
        TYPE T_RECORD IS RECORD (
            GOODS_CODE VARCHAR2 (64),
            GOODS_NAME VARCHAR2 (64)
        ) ;
        --定义返回结果集接收的变量,类型为T_RECORD;
      PS:这里也可以不用record,直接指定V_ROWRESUT为%rowtype类型
        V_ROWRESUT T_RECORD ;
        --定义主键
        PID VARCHAR2 (256) ;
        /*2.定义变量 end*/
    
    
            /*3.定义游标,执行查询结果集操作 START*/
            CURSOR CUR_RE_USER_ORD_GOODS
            IS
                    --查询语句开始
                    SELECT
                            A .GOODS_CODE,
                            B.GOODS_NAME
                    FROM
                            (
                                SELECT
                                        ORD.GOODS_CODE
                                FROM
                                        ORDER_INFO ORD
                                GROUP BY
                                        ORD.GOODS_CODE
                            ) A
                    LEFT JOIN GOODS_INFO B ON A .GOODS_CODE = B.GOODS_CODE ;
                    --查询语句结束
            /*3.定义游标,执行查询结果集操作 END*/
    
            /*4.打开并循环游标,进行数据操作 START*/
            BEGIN
                OPEN CUR_RE_USER_ORD_GOODS;                          --打开游标;
                LOOP                                                 --开始执行循环,遍历查询结果集表;
                    FETCH CUR_RE_USER_ORD_GOODS INTO V_ROWRESUT;       --循环游标并赋值给结构体变量;
                    EXIT WHEN CUR_RE_USER_ORD_GOODS %NOTFOUND;         --如果游标遍历完成,就退出循环;
    
                    --获取 UUID 并赋值给 PID 变量;
                    SELECT SYS_GUID() INTO PID FROM DUAL;
    
                    --插入“订购商品记录表” 开始
                    INSERT INTO RE_USER_ORD_GOODS (
                        ID,
                        GOODS_CODE,
                        GOODS_NAME,
                        CREATE_TIME
                    )VALUES(
                        PID,
                        V_ROWRESUT.GOODS_CODE,
                        V_ROWRESUT.GOODS_NAME,
                        SYSDATE
                    );
                    --插入“订购商品记录表” 结束
    
                END LOOP;                                           --结束循环;
                CLOSE CUR_RE_USER_ORD_GOODS;                        --关闭游标;
                COMMIT;                                             --提交 INSERT 操作;
            END;
            /*4.打开并循环游标,进行数据操作 END*/
    

    10.2 oracle存储过程中is和as区别

    在存储过程(PROCEDURE)和函数(FUNCTION)中没有区别;
    在视图(VIEW)中只能用AS不能用IS;
    在游标(CURSOR)中只能用IS不能用AS。

    10.3 声明变量的方式

    v_temp varchar(10)
    v_temp tablename.property%type(表名属性名%type,指的是一个表中某个字段的类型,这样可以灵活使用)
    v_stu    student%rowtype;(这种类型就是定义一个变量,这个变量的类型为一个表数据的行类型,用于接收查询的一整行数据)

    10.4 赋值方式

    :=


    转载自:有梦想的肥宅

  • 相关阅读:
    Google Chrome 自定义协议(PROTOCOL)问题的处理
    C# 6.0/7.0 的新特性
    MySQL 5.7.18 压缩包版配置记录
    nginx.conf文件内容详解
    博客添加动态动漫妹子
    TypeScript 3.8beta版
    微信浏览器H5开发常见的坑
    Babel7知识梳理
    雅虎前端优化35条规则
    webpack
  • 原文地址:https://www.cnblogs.com/cy-8593/p/12559331.html
Copyright © 2011-2022 走看看