包package
- 将功能相近的函数或存储过程组织在一起
- 便于管理
- 包内的函数可以重名,提高程序的通用性
- 减少对象的名称占用问题
- 一个包内函数使用,整个包都调入内存
- 包内一个程序失效,整个包重新编译
- 由包头和包体组成
包头
- 不能加密
- 描述了包内的函数,存储过程的参数
- 可以独立存在
包体
- 可以加密
- 函数的实现
- 不能独立存在
实验42:编写包package
建立包头
SQL> create or replace package pk87 is
function F1(no number) return number;
function F1(no emp.ename%type) return number;
procedure P1(v_no number);
end pk87;
/
程序包已创建。
建立包体
SQL> create or replace package body pk87 is
function F1
(no in number)
return number
is
v_salary emp.sal%type :=0;
begin
select sal into v_salary from emp where empno=no;
return v_salary;
end F1;
function F1
(no emp.ename%type)
return number
is
v_salary emp.sal%type :=0;
begin
select sal into v_salary from emp where ename = no;
return v_salary;
end F1;
procedure P1(v_no in number)
is
begin
update emp set sal=sal+1 where empno=v_no;
commit;
end P1;
end pk87;
/
程序包体已创建。
验证包内函数
SQL> select text from user_source where name='PK87';
TEXT
--------------------------------------------------------------------------------
package pk87 is
function F1(no number) return number;
function F1(no emp.ename%type) return number;
procedure P1(v_no number);
end pk87;
package body pk87 is
function F1
(no in number)
return number
is
v_salary emp.sal%type :=0;
TEXT
--------------------------------------------------------------------------------
begin
select sal into v_salary from emp where empno=no;
return v_salary;
end F1;
function F1
(no emp.ename%type)
return number
is
v_salary emp.sal%type :=0;
begin
select sal into v_salary from emp where ename = no;
TEXT
--------------------------------------------------------------------------------
return v_salary;
end F1;
procedure P1(v_no in number)
is
begin
update emp set sal=sal+1 where empno=v_no;
commit;
end P1;
end pk87;
已选择32行。
SQL> desc pk87
FUNCTION F1 RETURNS NUMBER
参数名称 类型 输入/输出默认值?
------------------------------ ----------------------- ------ --------
NO NUMBER IN
FUNCTION F1 RETURNS NUMBER
参数名称 类型 输入/输出默认值?
------------------------------ ----------------------- ------ --------
NO VARCHAR2(10) IN
PROCEDURE P1
参数名称 类型 输入/输出默认值?
------------------------------ ----------------------- ------ --------
V_NO NUMBER IN
调用包内函数
SQL> select pk87.f1(7900),pk87.F1('KING') FROM dual;
PK87.F1(7900) PK87.F1('KING')
------------- ---------------
950 5000
SQL> declare
v1 emp.sal%type;
v2 emp.ename%type;
begin
v1:=pk87.F1(7900);
v2:=pk87.F1('KING');
pk87.P1(7902);
dbms_output.put_line(v1);
dbms_output.put_line(v2);
end;
/
PL/SQL 过程已成功完成。
函数和包的相互依存关系
存在共同的同义词,又存在相应的同名称的表,先造数据。
·创建用户yoyo
SQL> conn / as sysdba
已连接。
SQL> create user yoyo identified by yoyo;
用户已创建。
·给用户yoyo授权
SQL> GRANT CREATE SESSION, CREATE ANY TABLE , CREATE ANY VIEW , CREATE ANY INDEX ,
CREATE ANY PROCEDURE ,
ALTER ANY TABLE , ALTER ANY PROCEDURE ,
DROP ANY TABLE , DROP ANY VIEW , DROP ANY INDEX , DROP ANY PROCEDURE ,
SELECT ANY TABLE , INSERT ANY TABLE , UPDATE ANY TABLE , DELETE ANY TABLE
TO yoyo;
授权成功。
SQL> GRANT CONNECT,RESOURCE TO yoyo;
授权成功。
·创建实验表emp
SQL> conn yoyo/yoyo
已连接。
SQL> CREATE TABLE emp(id NUMBER,last_name VARCHAR2(20),salary NUMBER);
表已创建。
SQL> select * from tab;
TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
EMP TABLE
SQL> desc emp;
名称 是否为空? 类型
----------------------------------------- -------- ----------------------------
ID NUMBER
LAST_NAME VARCHAR2(20)
SALARY NUMBER
·为emp表插入几条数据
SQL> insert into emp(id,last_name,salary) values(1001,'TOM',2400);
已创建 1 行。
SQL> insert into emp(id,last_name,salary) values(1002,'JIM',3100);
已创建 1 行。
SQL> insert into emp(id,last_name,salary) values(1003,'LILY',1300)
已创建 1 行。
SQL> select * from emp;
ID LAST_NAME SALARY
---------- -------------------- ----------
1001 TOM 2400
1002 JIM 3100
1003 LILY 1300
建立公共同义词
SQL> conn / as sysdba
已连接。
SQL> drop public synonym eee ;
drop public synonym eee
*
第 1 行出现错误:
ORA-01432: 要删除的公用同义词不存在
SQL> create public synonym eee for yoyo.emp;
同义词已创建。
·给scott授权可以查询yoyo用户的emp表
SQL> conn yoyo/yoyo
已连接。
SQL> grant select on emp to scott;
授权成功。
·验证授权
SQL> conn scott/scott
已连接。
SQL> select * from yoyo.emp;
ID LAST_NAME SALARY
---------- -------------------- ----------
1001 TOM 2400
1002 JIM 3100
1003 LILY 1300
·建立视图
SQL> drop view v1;
视图已删除。
SQL> create view v1 as select last_name from eee where rownum<2;
视图已创建。
SQL> select * from v1;
LAST_NAME
--------------------
TOM
·建立表
SQL> drop table eee purge;
表已删除。
SQL> create table eee as select * from yoyo.emp where rownum<3;
表已创建。
SQL> select * from v1;
LAST_NAME
--------------------
TOM
SQL> select object_name,status from user_objects;
OBJECT_NAME STATUS
-------------------- -------
PK_DEPT VALID
DEPT VALID
EMP VALID
PK_EMP VALID
BONUS VALID
SALGRADE VALID
EEE VALID
V1 VALID
已选择8行。
SQL> select * from eee;
ID LAST_NAME SALARY
---------- -------------------- ----------
1001 TOM 2400
1002 JIM 3100