练习 1:

--创建package header

CREATE OR REPLACE PACKAGE emp_pack

IS

PROCEDURE new_emp

(v_ename emp.ename%TYPE,

v_job emp.job%TYPE DEFAULT 'SALESMAN',

v_mgr emp.mgr%TYPE DEFAULT 7839,

v_sal emp.sal%TYPE DEFAULT 1000,

v_comm emp.comm%TYPE DEFAULT 0,

v_deptno emp.deptno%TYPE DEFAULT 30);

END emp_pack;

/


--创建package body

CREATE OR REPLACE PACKAGE BODY emp_pack

IS

FUNCTION valid_deptno --私有函数

(v_deptno IN dept.deptno%TYPE)

RETURN BOOLEAN

IS

v_dummy VARCHAR2(1);

BEGIN

SELECT 'x'

INTO v_dummy

FROM dept

WHERE deptno = v_deptno;

RETURN (TRUE);

EXCEPTION

WHEN NO_DATA_FOUND THEN

RETURN(FALSE);

END valid_deptno;


PROCEDURE new_emp

(v_ename emp.ename%TYPE,

v_job emp.job%TYPE DEFAULT 'SALESMAN',

v_mgr emp.mgr%TYPE DEFAULT 7839,

v_sal emp.sal%TYPE DEFAULT 1000,

v_comm emp.comm%TYPE DEFAULT 0,

v_deptno emp.deptno%TYPE DEFAULT 30)

IS

BEGIN

IF valid_deptno(v_deptno) THEN

INSERT INTO emp

VALUES (seq_empno.NEXTVAL, v_ename, v_job, v_mgr,

TRUNC (SYSDATE, 'DD'), v_sal, v_comm, v_deptno);

ELSE

DBMS_OUTPUT.PUT_LINE('Invalid department number. Try again.');

END IF;

END new_emp;

END emp_pack;

/


为PACKAGE BODY加密:

wrap iname=1.sql

sql>@1.plb

----------------------------------------------------------------------

练习 2:重载

--创建package header

CREATE OR REPLACE PACKAGE over_load is

FUNCTION print_it(v_arg date)

RETURN VARCHAR2;

FUNCTION print_it(v_arg VARCHAR2)

RETURN VARCHAR2;

END over_load;

/


--创建package body

CREATE OR REPLACE PACKAGE BODY over_load is

FUNCTION print_it(v_arg date)

RETURN VARCHAR2

IS

BEGIN

RETURN to_char(v_arg,'yyyy-mm-dd');

END print_it;


FUNCTION print_it(v_arg VARCHAR2)

RETURN VARCHAR2

IS

BEGIN

RETURN to_char(v_arg,'L99,999.00');

END print_it;

END over_load;

/



--包的调用

VARIABLE g_datevalue varchar2(40);

execute :g_datevalue := over_load.PRINT_IT(sysdate);

print g_datevalue


VARIABLE g_datevalue varchar2(40);

execute :g_datevalue := over_load.PRINT_IT('123');

print g_datevalue

----------------------------------------------------------------------

包与依赖:断开了依赖链

DROP TABLE T;

create table t (x int);


create view v as select * from t;


create procedure p

is

begin

for x in (select * from v)

loop

null;

end loop;

end;

/


create function f return number

is

l_cnt number;

begin

select count(*) into l_cnt from t;

return l_cnt;

end;

/


查看依赖关系:


select name,type,referenced_name,referenced_type

from user_DEPENDENCIES

where name IN ('F','P','T','V')

AND referenced_owner='SCOTT'

order by name;


查看对象有效状态:


select object_name,object_type,status

from user_objects

where object_name in ('F','P','T','V');


修改T表结构后,再看有效性:


alter table t add y number;


select object_name,object_type,status

from user_objects

where object_name in ('F','P','T','V');


V P F 无效


创建一个依赖P的过程后,再看有效性:

create procedure p2

is

begin

p;

end;

/


select object_name,object_type,status

from user_objects

where object_name in ('F','P','P2','T','V');


V P 重新有效!对P2的编译同时重新编译了V P!


使用包重做上面的实验:


create package pk1

is

procedure p;

end;

/


create package body pk1

is

procedure p

is

begin

for x in (select * from v)

loop

null;

end loop;

end;

end pk1;

/


create package pk2

is

procedure p;

end;

/


create package body pk2

is

procedure p

is

begin

pk1.p;

end;

end pk2;

/


select object_name,object_type,status

from user_objects

where object_name in ('F','P','P2','T','V','PK1','PK2');


再次修改T,再查看有效性!PK1 包体无效了!因为PK1 包体通过V依赖与T(依赖链)

而PK2仍然有效!PK2依赖与PK1而不是PK1包体(因而断开了依赖链)!


exec pk2.p;


select object_name,object_type,status

from user_objects

where object_name in ('F','P','P2','T','V','PK1','PK2');