oracle 游标(cursor)&&记录集(record)

1.定义游标

cursor cursor_name is select_statement;

2.打开游标

执行对应的SELECT语句并将SELECT语句的结果暂时存放到结果集中.

open cursor_name;

3.提取数据

打开游标后,SELECT语句的结果被临时存放到游标结果集中,使用FETCH语句只能提取一行数据

通过使用FETCH..BULK COLLECT INTO语句每次可以提取多行数据

例子:

 游标的使用步骤:

      1.声明一个游标

      2.打开游标 open 游标名(参数1,参数2..);

      3.使用循环遍历游标,从游标中取值。fetch 游标名 into 变量名,循环的退出条件是 游标名%notfound;

      4.关闭游标 close 游标名;

cursor 游标名(游标输入参数)
is select语句
-- 游标参数可以有多个
--------------------------------------
游标中使用fetch..into语句:只能处理一行数据,除非用循环语句
--------------------------------------
--匿名块
declare
 --游标的定义
  CURSOR emp_cur IS
  select empno,ename,job from scott.emp;
 emp_row emp_cur%rowtype;--定一个和游标一样类型的集合
 BEGIN
  --打开游标
  OPEN emp_cur;
  LOOP
  --提取游标中的数据到emp_row
   FETCH emp_cur into emp_row;
   EXIT WHEN emp_cur%notfound;
   dbms_output.put_line(emp_row.empno||','||emp_row.ename);
  END LOOP;
  --关闭游标
  CLOSE emp_cur;
 END;
----
或者
--- 
--匿名块 方法2
declare
 --游标的定义
  CURSOR emp_cur IS
  select empno,ename,job from scott.emp;
 emp_row emp_cur%rowtype;--定一个和游标一样类型的集合
 BEGIN
  --打开游标
  OPEN emp_cur;
    FETCH emp_cur into emp_row;--预先Fetch一次
   while emp_cur%found LOOP
   dbms_output.put_line(emp_row.empno||','||emp_row.ename);
   FETCH emp_cur into emp_row;
  END LOOP;
  --关闭游标
  CLOSE emp_cur;
 END;
 --------

2.使用for循环遍历游标

使用for循环遍历游标的好处:1.不用声明额外的变量,2.不用打开和关闭游标,3.写法简单。

(使用FOR循环时,ORACLE会隐含的打开游标,提取游标数据并关闭游标。每循环一次提取一次数据,在提取了所有数据后,自动退出循环并隐含的关闭游标。)

--匿名块
declare
 --游标的定义
  CURSOR emp_cur IS
  select empno,ename,job from scott.emp;
 emp_row emp_cur%rowtype;--定一个和游标一样类型的集合
 BEGIN
  FOR row in emp_cur LOOP
   dbms_output.put_line(row.empno||','||row.ename);
  end loop
 END;

3.通过bulk collect减少loop处理的开销

--匿名块
declare
 --游标的定义
  CURSOR emp_cur IS
  select empno,ename,job from scott.emp;
 type ename_table_type is table of emp_cur%rowtype ;
    ename_table ename_table_type;
 BEGIN
  --打开游标
  OPEN emp_cur;
  LOOP
  --提取游标中的数据到emp_row
   FETCH emp_cur bulk coollect into ename_table;
    for x in 1..ename_table.count loop
   dbms_output.put_line(ename_table(x).empno||','||ename_table(x).ename);
  END LOOP;
  --关闭游标
  CLOSE emp_cur;
 END;

记录(RECORD)

一,什么是记录(Record)?
 由单行多列的标量构成的复合结构。可以看做是一种用户自定义数据类型。组成类似于多维数组。
将一个或多个标量封装成一个对象进行操作。是一种临时复合对象类型。
 
 记录可以直接赋值。RECORD1 :=RECORD2;
 记录不可以整体比较.
 记录不可以整体判断为空。
 
二,%ROWTYPE和记录(Record)?
 请区别%ROWTYPE和记录(Record)类型。%ROWTYPE可以说是Record的升级简化版。
 区别在与前者结构为表结构,后者为自定义结构。二者在使用上没有很大区别。前者方便,后者灵活。在实际中根据情况来具体决定使用。
 Record + PL/SQL表可以进行数据的多行多列存储。

DECLARE
  Type MyRecType Is  Record
  (
   RENO  EMPA.EMPNO%Type,
   RENAME   VARCHAR2(10),
   RJOB   EMPA.JOB%Type
  );
  EmpRec MyRecType; 
 Begin
  Select   EMPNO, ENAME, JOB  InTo  EmpRec  From scott.emp Where empa.EMPNO = '7369';
  DBMS_OUTPUT.PUT_LINE(EmpRec.RENO||'  '||EmpRec.RENAME||'  '||EmpRec.RJOB);
  
  EmpRec.RENO  := 1321;
  EmpRec.RENAME := 'eaves';
  EmpRec.RJOB  := 'programer';

  DBMS_OUTPUT.PUT_LINE(EmpRec.RENO||'  '||EmpRec.RENAME||'  '||EmpRec.RJOB);
 End;