33.PLSQL中的包

一、引言

        PLSQL中的包类似于C++中的类,在包中我们可以定义变量、游标、存储过程、存储函数等等。它实现了将上述类型统一创建和管理,同时在不同包之间这个PLSQL的对象不会存在命名冲突问题。包的定义包含两部分,包头和包体,有点类似于C++中的类的头文件和cpp文件。在包头中我们对变量、存储过程等等进行声明,而在包体中是对他们的实现。下面,我们在emp表的基础之上介绍包的用法。如下,假设有以下的emp表:

二、包的定义

        我们将创建一个名叫emp_page的包,包中包含一个存储过程insert_emp用来向emp表中插入数据,一个存储函数get_emp_func,根据部门号返回该部门所有雇员的信息。

2.1 包头定义 

create or replace package emp_pack
as
  function get_emp_func(p_dno dept.deptno%type) return sys_refcursor;
  procedure insert_emp(v_empno emp.empno%type,v_ename emp.ename%type,v_job emp.job%type,v_mgr emp.mgr%type,v_sal emp.sal%type,v_deptno emp.deptno%type);
end;
/
        可以看到我们在包头中分别声明了存储过程insert_emp和存储函数get_emp_func,包头中只负责声明,我们需要在包体中进行实现。需要特别注意的是编写完包头和包体之后,我们要先编译包头再去编译包体,才能正确完成一个包的创建。

2.2 包体定义

create or replace package body emp_pack
as
  function get_emp_func(p_dno dept.deptno%type) return sys_refcursor
  as
   v_cur sys_refcursor;
  begin
   open v_cur for select * from emp where deptno=p_dno;
   return v_cur;
  end;
  procedure insert_emp(v_empno emp.empno%type,v_ename emp.ename%type,v_job emp.job%type,v_mgr emp.mgr%type,v_sal emp.sal%type,v_deptno emp.deptno%type)
as 
 v_count number;
begin
  select count(*) into v_count from emp where empno=v_empno;
  if v_count>0 then
   raise_application_error(-20789,'增加失败,该部门已经存在');
  else
   insert into emp values(v_empno,v_ename,v_job,v_mgr,sysdate,v_sal,null,v_deptno);
  end if;
  commit;
exception
  when others then
      dbms_output.put_line('sqlerrm='||sqlerrm);
      rollback;
end;
end;
/

        包体的创建语法中,与包头唯一不同之处在于在package后面加了一个body关键字,接下来就是对包头中定义的内容的实现。get_emp_func接收一个部门号的参数,在函数内部定义了一个系统参考游标,用来接收该部门对应的雇员,并最终返回这个游标;insert_emp中接收一个雇员的信息,将他插入emp表中。完成上述代码之后,分别对包头和包体进行编译,一个包就被定义好了,我们可以用sql developer看到我们创建的包:

三、包的使用

        创建完包之后,我们可以在PLSQL的程序块中使用包里的函数或者过程,如下的例子我们使用一个系统的参考游标接收了包中
get_emp_func返回的游标,并打印出游标管理的结果集:
declare
  v_cur sys_refcursor;
  v_emp emp%rowtype;
begin
  v_cur:=emp_pack.get_emp_func(20);
  fetch v_cur into v_emp;
  while v_cur%found loop
    dbms_output.put_line('姓名:'||v_emp.ename||',薪资:'||v_emp.sal);
    fetch v_cur into v_emp;
  end loop;
  close v_cur;
end;
/

结果如下:

四、使用包中的变量

        包中出了可以定义存储过程和存储函数之外,我们也可以定义一个变量供外部使用,如,我们在包头增加一个v_empno的变量:
create or replace package emp_pack
as
  v_empno emp.empno%type :=10;
  function get_emp_func(p_dno dept.deptno%type) return sys_refcursor;
  procedure insert_emp(v_empno emp.empno%type,v_ename emp.ename%type,v_job emp.job%type,v_mgr emp.mgr%type,v_sal emp.sal%type,v_deptno emp.deptno%type);
end;
/
        增加完之后要重新编译包头和包体,然后直接可以在PLSQL代码块中使用该变量:
begin
  dbms_output.put_line(emp_pack.v_empno);
end;
/
        结果如下:





















  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值