博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
oracle 对象管理 08_游标与记录
阅读量:6897 次
发布时间:2019-06-27

本文共 4435 字,大约阅读时间需要 14 分钟。

hot3.png

一、游标定义

1.游标是查询结果集的平面化展示,通过游标方便定位到结果集中某个特定的行。
2.游标的分类
    显示游标:即用户自定义游标,专门用于处理select语句返回的多行数据
    隐式游标:系统自动定义的游标,记录集只有单行数据,用于处理select into 和DML语句
3.游标使用的一般过程:
    显示游标:声明, 打开, 读取, 关闭
    隐式游标:直接使用读取,声明、打开、关闭都是系统自动进行的
4显示游标的过程描述
a.声明游标
    CURSOR cursor_name IS select_statement
    如:CURSOR emp_cur IS SELECT empno,ename,job,sal FROM scott.emp;
b.打开游标,打开游标则执行对应的select语句,将对应的结果集存放到游标当中
    OPEN cursor_name     
c.获取数据,提取单行数据,需要配合循环语句来使用,提取多行数据,collect为集合变量
    FETCH cursor_name INTO var_name1,...var_name2 ;   
    FETCH cursor_name BULK COLLECT INTO collect1,collect2,...[LIMIT rows];    
d.关闭游标
    CLOSE cursor_name 
5.显示游标的5个属性
    cursor_name%ISOPEN         --游标是否打开   
    cursor_name%FOUND          --最近的FETCH是否提取到数据
    cursor_name%NOTFOUND       --最近的FETCH是否没有提取到数据
    cursor_name%ROWCOUNT       --返回到目前为止,已经从游标缓冲区中提取到数据的行数  
    
二、游标使用
1.输入job,输出ename,sal值
    declare
        v_name emp.ename%type;
        v_sal  emp.sal%type;
        cursor cur_one is select ename,sal from emp where job ='&input';
    begin
        open cur_one;
        dbms_output.put_line('ename          sal');
        loop
            fetch cur_one into v_name,v_sal;
            exit when (cur_one%notfound);
            dbms_output.put_line(v_name||'          '||v_sal);              
        end loop;
        close cur_one;
    end;
2.使用游标统一定义变量类型
    declare
        cursor cur_one is select ename,sal,job,mgr,hiredate,comm from emp where job ='&input';
        v_cur_col  cur_one%rowtype;
    begin
        open cur_one;
        dbms_output.put_line('ename          sal');
        loop
            fetch cur_one into v_cur_col;
            exit when (cur_one%notfound);
            dbms_output.put_line(v_cur_col.ename||'          '||v_cur_col.sal);              
        end loop;
        close cur_one;
    end;
3.游标FOR循环
    游标FOR循环是为了简化游标使用过程而设计的。使用游标FOR循环检索游标时,游标的打开、数据提取、数据是否检
索到的判断与游标的关闭都是ORACLE系统自动进行的。
    --显式
    DECLARE
      CURSOR CURSOR_006 IS
        SELECT ENAME, HIREDATE FROM EMP WHERE SAL < &SAL;
    BEGIN
      DBMS_OUTPUT.PUT_LINE('ename      hiredate');
      FOR V_CUR IN CURSOR_006 LOOP
        DBMS_OUTPUT.PUT_LINE(V_CUR.ENAME || '   ' || V_CUR.HIREDATE);
      END LOOP;
    END;
    --隐式
    BEGIN
      DBMS_OUTPUT.PUT_LINE('ename      hiredate');
      FOR V_CUR IN (SELECT ENAME, HIREDATE FROM EMP WHERE SAL < &SAL) LOOP
        DBMS_OUTPUT.PUT_LINE(V_CUR.ENAME || '   ' || V_CUR.HIREDATE);
      END LOOP;
    END;
    
三、记录
    是一个或多个字段且拥有数据类型的集合体,类似于表的数据结构,定义了PL/SQL记录类型之后,可以定义
PL/SQL记录变量,多用于简化单行多列的数据处理。
1.记录的定义
a.自定义记录成员
    TYPE TYPE_NAME IS RECORD                                      
        (field_name1 datatype1 [NOT NULL] [ := DEFAULT EXPRESSION],
         field_name2 datatype2 [NOT NULL] [ := DEFAULT EXPRESSION],
         ...
         field_nameN datatypeN [NOT NULL] [ := DEFAULT EXPRESSION]);
    record_name TYPE_NAME;
b.参照数据对象定义
    record_name table_name%rowtype
    record_name view_name%rowtype
    reocrd_name cursor_name%rowtype
    
四、记录的使用
1.使用记录及记录成员
    undefine no
    DECLARE
        TYPE emp_record_type IS RECORD
        (
            name emp.ename%TYPE,
            salary emp.sal%TYPE,
            dno emp.deptno%TYPE
        );
        emp_record emp_record_type;
    BEGIN                     
        SELECT ename, sal, deptno INTO emp_record --[select ename,sal into emp_record.name,emp_record.salary]
        FROM emp WHERE empno = &no;
        dbms_output.put_line(emp_record.name);   --输出时仅仅输出记录变量的一个成员emp_record.name
    END;
2.使用PL/SQL记录(记录成员)变量
    DECLARE
        dept_record dept%ROWTYPE;
    BEGIN
        dept_record.deptno := 50;
        dept_record.dname := 'ADMINISTRATOR';
        dept_record.loc := 'BEIJING';
        INSERT INTO dept VALUES dept_record;
    END;
3.记录使用的几个问题
a.记录成员非空时必须在定义时给初值
    DECLARE
    TYPE ex_type IS RECORD
        (col1 NUMBER(3),
         col2 VARCHAR2(5) NOT NULL);  --编译不通过
    ex_record ex_type;
    BEGIN
        ex_record.col1:=15;
        ex_record.col1:=TO_CHAR(ex_record.col1);
        ex_record.col2:='John';
        DBMS_OUTPUT.PUT_LINE('ex_record.col1 is '||ex_record.col1);
        DBMS_OUTPUT.PUT_LINE('ex_record.col2 is '||ex_record.col2);
    END;
    
    DECLARE
      TYPE ex_type IS RECORD(
        col1 NUMBER(3),
        col2 VARCHAR2(5) NOT NULL := 'John');  
      ex_record ex_type;
    BEGIN
      ex_record.col1 := 15;
      ex_record.col1 := TO_CHAR(ex_record.col1);
      ex_record.col2:='TOM';--可以赋新值
      DBMS_OUTPUT.PUT_LINE('ex_record.col1 is ' || ex_record.col1);
      DBMS_OUTPUT.PUT_LINE('ex_record.col2 is ' || ex_record.col2);
    END;
b.来自不同的记录类型的记录变量之间不能相互赋值
c.同一个记录的记录变量之间可以相互赋值
d.基于表,游标,自定义记录的使用
    DECLARE
      CURSOR dept_cur IS
         SELECT * FROM dept WHERE deptno = 30;
      TYPE dept_type IS RECORD( 
        deptno NUMBER(2),
        dname  VARCHAR2(14),
        loc    VARCHAR2(13));    
      dept_rec1 dept%ROWTYPE;     --声明基于表dept的记录变量
      dept_rec2 dept_cur%ROWTYPE; --声明基于游标dept_cur的记录变量
      dept_rec3 dept_type;        --声明基于自定义dept_type的记录变量    
    BEGIN
      SELECT * INTO dept_rec1 FROM dept WHERE deptno = 30;    
      OPEN dept_cur;
      LOOP
        FETCH dept_cur
          INTO dept_rec2; 
        EXIT WHEN dept_cur%NOTFOUND;
      END LOOP;    
      dept_rec1 := dept_rec2;
      dept_rec3 := dept_rec2;
    
      DBMS_OUTPUT.PUT_LINE(dept_rec1.deptno || ' ' || dept_rec1.dname);
      DBMS_OUTPUT.PUT_LINE(dept_rec2.deptno || ' ' || dept_rec2.dname);
      DBMS_OUTPUT.PUT_LINE(dept_rec3.deptno || ' ' || dept_rec3.dname);
    END;
 

转载于:https://my.oschina.net/peakfang/blog/2245392

你可能感兴趣的文章
Tensorflow 1.3版本更新概览
查看>>
Spark比拼Flink:下一代大数据计算引擎之争,谁主沉浮?
查看>>
jDays 2016综合报道
查看>>
通过Visual Studio为Linux编写C++代码
查看>>
利用已有的大数据技术,如何构建机器学习平台
查看>>
阿里云9月1日安骑士升级故障真相
查看>>
【树莓派系列】一.准备工作与开机
查看>>
Reddit引入Envoy支持架构改造,性能显著提升
查看>>
Java Nestmate稳步推进
查看>>
试水区块链出版?纽约时报在招人了
查看>>
Vaadin发布Polyglot框架第8版
查看>>
vim + syntastic + verilator or iverilog
查看>>
git 简略笔记之三 -- 使用 github 管理项目
查看>>
CentOS7.0下编译安装PHP 5.6.21
查看>>
指针和字符串和字符串常量、用gdb来获取非法内存中的内容
查看>>
分析递归程序比较好的画图法
查看>>
图像形态学的几种基本操作 Image Morphology
查看>>
2015 杭州黑客马拉松赛后随笔
查看>>
青阳网络文件传输系统 kiftd 1.0.17 正式发布
查看>>
搞懂Mysql InnoDB B+树索引
查看>>