ORACLE PL/SQL 包

 

包对比java

  • 包相当于java中的类,过程和函数相当于类的方法,变量相当于成员变量
  • 包中的程序元素也分为公用元素(外包可用)和私用元素(同包)两种
  • 当程序首次调用包内函数或过程时,ORACLE将整个包调入内存,当再次访问包内元素时,ORACLE直接从内存中读取

一个包由两个分开的部分组成:

  • 包定义(PACKAGE):包定义部分声明包内数据类型、变量、常量、游标、子程序和异常错误处理等元素,这些元素为包的公有元素。
  • 包主体(PACKAGE BODY):包主体则是包定义部分的具体实现,它定义了包定义部分所声明的游标和子程序,在包主体中还可以声明包的私有元素。
  • 包定义和包主体分开编译,并作为两部分分开的对象存放在数据库字典中。

包定义的语法如下:
CREATE [OR REPLACE] PACKAGE package_name
{IS | AS}
[公有数据类型定义[公有数据类型定义]…]
[公有游标声明[公有游标声明]…]
[公有变量、常量声明[公有变量、常量声明]…]
[公有子程序声明[公有子程序声明]…]
END [package_name];


包体定义的语法如下:
CREATE [OR REPLACE] PACKAGE BODY package_name
{IS | AS}
[私有数据类型定义[私有数据类型定义]…]
[私有变量、常量声明[私有变量、常量声明]…]
[私有子程序声明和定义[私有子程序声明和定义]…]
[公有子程序定义[公有子程序定义]…]
BEGIN
PL/SQL 语句
END [package_name];
其中:在包主体定义公有程序时,它们必须与包定义中所声明子程序的格式完全一致


包的开发步骤:

  • 将每个存储过程调式正确
  • 用文本编辑软件将各个存储过程和函数集成在一起
  • 按照包的定义要求将集成的文本的前面加上包定义
  • 按照包的定义要求将集成的文本的前面加上包主体
  • 使用开发工具进行调式

例:

 1 CREATE OR REPLACE PACKAGE demo_pack
 2   IS
 3   DeptRec dept%ROWTYPE;
 4 FUNCTION add_dept(
 5   dept_no NUMBER, dept_name VARCHAR2,
 6   location VARCHAR2)
 7   RETURN NUMBER;
 8   FUNCTION remove_dept(dept_no NUMBER)
 9   RETURN NUMBER;
10   PROCEDURE query_dept(dept_no IN NUMBER);
11 END demo_pack;
12 
13 CREATE OR REPLACE PACKAGE BODY demo_pack
14   IS 
15   FUNCTION add_dept
16   (dept_no NUMBER, dept_name VARCHAR2, location VARCHAR2)
17   RETURN NUMBER
18   IS 
19   empno_remaining EXCEPTION;
20   PRAGMA EXCEPTION_INIT(empno_remaining, -1);
21   /* -1 是违反唯一约束条件的错误代码 */
22 BEGIN
23   INSERT INTO dept VALUES(dept_no, dept_name, location);
24   IF SQL%FOUND THEN
25   RETURN 1;
26   END IF;
27 EXCEPTION
28   WHEN empno_remaining THEN 
29     RETURN 0;
30   WHEN OTHERS THEN
31     RETURN -1;
32   END add_dept;
33 
34 PROCEDURE query_dept
35   (dept_no IN NUMBER)
36   IS
37 BEGIN
38   SELECT * INTO DeptRec FROM dept WHERE deptno=dept_no;
39 EXCEPTION
40   WHEN NO_DATA_FOUND THEN 
41     DBMS_OUTPUT.PUT_LINE('数据库中没有编码为'||dept_no||'的部门');
42   WHEN TOO_MANY_ROWS THEN
43     DBMS_OUTPUT.PUT_LINE('程序运行错误!请使用游标');
44   WHEN OTHERS THEN
45     DBMS_OUTPUT.PUT_LINE(SQLCODE||'----'||SQLERRM);
46   END query_dept;
47 END demo_pack;

调用包

例:

 1 DECLARE
 2 Var NUMBER;
 3 BEGIN
 4 Var := demo_pack.add_dept(90,'Administration', 'Beijing');
 5 IF var =-1 THEN
 6 DBMS_OUTPUT.PUT_LINE(SQLCODE||'----'||SQLERRM);
 7 ELSIF var =0 THEN
 8 DBMS_OUTPUT.PUT_LINE('该部门记录已经存在!');
 9 ELSE
10 DBMS_OUTPUT.PUT_LINE('添加记录成功!');
11 Demo_pack.query_dept(90);
12 DBMS_OUTPUT.PUT_LINE(demo_pack.DeptRec.deptno||'---'||
13 demo_pack.DeptRec.dname||'---'||demo_pack.DeptRec.loc);
14 var := demo_pack.remove_dept(90);
15 IF var =-1 THEN
16 DBMS_OUTPUT.PUT_LINE(SQLCODE||'----'||SQLERRM);
17 ELSIF var=0 THEN
18 DBMS_OUTPUT.PUT_LINE('该部门记录不存在!');
19 ELSE
20 DBMS_OUTPUT.PUT_LINE('删除记录成功!');
21 END IF;
22 END IF;
23 END; 


可以使用 DROP PACKAGE 命令对不需要的包进行删除,语法如下:
例:DROP PACKAGE emp_package;

包所涉及到的数据字典视图:
DBA_SOURCE, USER_SOURCE, USER_ERRORS, DBA-OBJECTS

 

 

 

原文地址:https://www.cnblogs.com/-maji/p/7265100.html