8.程序包:
建立一个包标准:
create or replace package test
as
--公共变量
v_code int;
v_msg varchar2(2000);
--公共常量
C_SUCCESS constant int:=1;
C_EX_PK constant int:=-1;
C_EX_FK constant int:=-2291;
c_EX_NOTNULL constant int:=-1400;
--公共异常
e_notnull exception;
pragma exception_init(e_notnull,-1400);
e_fk exception;
pragma exception_init(e_fk,-2291);
--以上的元素无需实现,在包体中可以使用,外部程序也可以使用
--子程序只提供声明,具体的实现代码需要在包体中完成
--公共函数
function get_salary
(v_empno emp.empno%type)
return number;
--公共过程
procedure add_emp
(v_empno emp.empno%type,
v_ename emp.ename%type,
v_deptno emp.deptno%type,
v_resultset out sys_refcursor);
end;
create or replace package body test
as
--没有在包标准中声明,必然是私有函数,此函数只能在包内部使用,外部程序不可见
function chk_emp
(v_empno emp.empno%type)
return boolean
as
v_num int;
begin
select count(*) into v_num from emp where empno=v_empno;
if v_num=0 then
return false;
else
return true;
end if;
end;
--重载chk_emp函数,因为v_ename和v_empno两个形参的类型不同,可以实现重载
function chk_emp
(v_ename emp.ename%type)
return boolean
as
v_num int;
begin
select count(*) into v_num from emp where upper(ename)=upper(v_ename);
if v_num=0 then
return false;
else
return true;
end if;
end;
--下面的子程序是公共的,因为这些子程序在包标准部分已经声明了
function get_salary
(v_empno emp.empno%type)
return number
as
v_sal number(10,2);
begin
if chk_emp(v_empno) then
select (sal+nvl(comm,0))*12 into v_sal from emp where empno=v_empno;
return v_sal;
else
return 0;
end if;
end;
procedure add_emp
(v_empno emp.empno%type,
v_ename emp.ename%type,
v_deptno emp.deptno%type,
v_resultset out sys_refcursor)
as
--把程序中声明的局部异常,放到程序包标准部分,这些异常就可以被Oracle中所有程序使用
begin
insert into emp(empno,ename,deptno)
values(v_empno,v_ename,v_deptno);
if SQL%found then
v_code:=C_SUCCESS;
commit;
open v_resultset for select * from emp where empno=v_empno;
end if;
exception
when others then
v_code:=SQLCODE;
v_msg:=SQLERRM;
end;
begin
--初始化
v_code:=0;
v_msg:='这是变量的初始化';
end;
--测试程序
--公共变量、常量、异常等的使用方法
declare
v_resultset sys_refcursor;
v_row emp%rowtype;
begin
test.add_emp(&empno,&ename,&deptno,v_resultset);
if test.v_code=1 then
loop
fetch v_resultset into v_row;
exit when v_resultset%notfound;
dbms_output.put_line(v_row.ename);
end loop;
else
dbms_output.put_line(test.v_msg);
end if;
end;
调用:
exec 包名.方法名(参数);