一、游标
显示游标
格式:
1.定义游标 后面练习中游标名均为 cur_emp
cursor 游标名 is 结果集; |
2.打开游标
open cur_emp; |
3 执行操作
fetch cur_emp into 变量; |
4 关闭游标
close cur_emp; |
隐示游标
默认游标名:SQL
SQL%rowcount 指向最近的一次隐示游标
注意:① 游标变量不能用for
② 不能把两个由不同游标产生的游标变量相互赋值
格式:
⒈ 定义
弱类型
type 游标变量名(eg: ref_emp) is ref cursor; |
强类型
type 游标变量名(eg: ref_emp) is ref cursor return 类型(eg: emp%rowtype); |
2. 定义游标变量
cur_emp ref_emp; |
3. 指向结果集
open cur_emp for 结果集 (eg: select ename from emp where empno=1234); |
4. 使用游标
fetch cur_emp into 变量(eg: v_ename); |
5. 关闭游标
Close cur_emp; |
练习
1. 查 deptno=10的 ename
set serverout on;
declare type ref_emp is ref cursor; cur_emp ref_emp; v_ename emp.ename%type; begin open cur_emp for select ename from emp where deptno=10; fetch cur_emp into v_ename; while cur_emp%found loop dbms_output.put_line(v_ename); fetch cur_emp into v_ename; end loop; if cur_emp%isopen then close cur_emp; end if; end; / |
二、包
1. 包头定义
create or replace package emp_package is 定义变量 eg: type ref_emp is ref cursor; 函数定义 eg: function f_findByLoc (参数 eg: f_loc dept.loc%type) return ref_emp; 注意: 包头中此 ; 需要 end; / |
2. 包体定义
create or replace package body emp_package is 函数定义 eg: function f_findByLoc (参数 eg: f_loc dept.loc%type) return ref_emp 注意: 包体中此处不需要 ; is cur_emp ref_emp; begin 执行过程 end; end; / |
总结:如何创建包头
create or replace package 包名{定义的变量等}
创建包身:create orplace package body 包名(注意要和包头名一样)
{函数等方法的具体的定义
}
例1:查询出 Dept.loc=’DALLAS’ 所有员工的 ename ,sal
create or replace package emp_package is type ref_emp is ref cursor; function f_findByLoc (f_loc dept.loc%type) return ref_emp; end; /
create or replace package body emp_package is function f_findByLoc (f_loc dept.loc%type) return ref_emp is cur_emp ref_emp; begin open cur_emp for select ename,sal from emp inner join dept on emp.deptno = dept.deptno where dept.loc=f_loc; return cur_emp; end; end; /
declare cur_emp emp_package.ref_emp; v_ename emp.ename%type; v_sal emp.sal%type; begin cur_emp:=emp_package.f_findByLoc(' DALLAS '); fetch cur_emp into v_ename,v_sal; while cur_emp%found loop dbms_output.put_line(v_ename||' '||v_sal); fetch cur_emp into v_ename,v_sal; end loop; if cur_emp%isopen then close cur_emp; end if; end; / |
结果:
SMITH 800 JONES 2975 SCOTT 3000 ADAMS 1100 FORD 3000 |
例2:输入部门名,得出该部门中的人的所有信息
首先建立个包里面放个游标
create or replace package emp_cur is type cur1 is ref cursor; end; |
包的调用请看下面的函数
create or replace function emp_ename(v_dname dept.dname%type) return emp_cur.cur1 is cur_all emp_cur.cur1; 这里就是调用包中的游标的方法 begin open cur_all for select ename,sal,hiredate from emp where deptno in(select deptno from dept where dname=v_dname); return cur_all; end; |
实现调用该函数的具体代码如下:
declare cur_all emp_cur.cur1; f_dname dept.dname%type; v_ename emp.ename%type; v_sal emp.sal%type; v_hiredate emp.hiredate%type; begin f_dname:='SALES'; cur_all:=emp_ename(f_dname); fetch cur_all into v_ename,v_sal,v_hiredate; while cur_all%found loop dbms_output.put_line('员工名'||v_ename||'进公司年月'||v_hiredate||'工资'||v_sal); fetch cur_all into v_ename,v_sal,v_hiredate; end loop; if cur_all%isopen then close cur_all; end if; dbms_output.put_line(v_ename); end; |