更新时间:2025-09-19 GMT+08:00
分享

包(Package)

简介

包(Package)是一组相关的子程序,包括包所使用的游标和变量,一起存储在数据库中,以便作为一个单元继续使用。打包的子程序可以由应用程序或用户显式调用。具有以下特点:

  • 促进模块化编程:通过将相关的函数和存储过程封装在一个Package中,可以更容易地实现模块化编程。模块化可以提高代码的可读性和可维护性。
  • 断开依赖链:对某个数据库对象的修改(如表结构的更改)不会导致依赖于该对象的所有其他对象(如存储过程、函数、视图等)变得无效,从而避免了代价较高的重编译过程。
  • 性能优化:Package在数据库中是以编译形式存储的,当Package被调用时,数据库不需要再次编译代码,从而提高了执行效率。
  • 命名空间管理:Package提供了一种命名空间,可以避免不同模块之间的命名冲突。在同一个Package内,可以有不同的函数和过程,即使它们在其他上下文中有相同的名称也不会冲突。
  • 安全性:通过Package可以更好地控制对数据库对象的访问。

示例

创建包需要两部分内容,包头和包体。包头需要声明所有公共结构,而包体需要定义包的所有结构,包括公共部分和私有部分。

如下示例中,创建emp表,和pkg_emp_mgr包。包中有三个存储过程。

  • pkg_emp_mgr.emp_add往emp表中插入员工信息。
  • pkg_emp_mgr.emp_del作用是删除emp表中员工信息。
  • pkg_emp_mgr.emp_res的作用是修改emp表中信息。
--创建emp表。
gaussdb=# CREATE TABLE emp(
    id INT,             -- 员工编号 
    name VARCHAR(50),   -- 员工姓名
    depno INT,          -- 部门编号
    sal FLOAT           -- 工资
);
CREATE TABLE

--创建包头。
gaussdb=# CREATE OR REPLACE PACKAGE pkg_emp_mgr AS 
    PROCEDURE emp_add(v_id INT, v_name VARCHAR, v_depno INT, v_sal FLOAT);
    PROCEDURE emp_del(v_id INT);
    PROCEDURE emp_res(v_id INT, v_depno INT, v_sal VARCHAR);
END pkg_emp_mgr;
/

--创建包体。
gaussdb=# CREATE OR REPLACE PACKAGE BODY pkg_emp_mgr AS 
    PROCEDURE emp_add(v_id INT, v_name VARCHAR, v_depno INT, v_sal FLOAT) AS 
    BEGIN
        INSERT INTO emp VALUES (v_id, v_name, v_depno, v_sal);
    END;
    PROCEDURE emp_del(v_id INT) AS 
    BEGIN
        DELETE FROM emp WHERE id = v_id;
    END;
    PROCEDURE emp_res(v_id INT, v_depno INT, v_sal VARCHAR) AS
    BEGIN
        UPDATE emp SET depno = v_depno, sal = v_sal WHERE id = v_id;
    END;
END pkg_emp_mgr;
/
--调用pkg_emp_mgr.emp_add添加员工信息。
gaussdb=# CALL pkg_emp_mgr.emp_add(1, 'scott', 10, 4000.00);
gaussdb=# CALL pkg_emp_mgr.emp_add(2, 'july', 20, 3000.00);
--查询表数据。
gaussdb=# SELECT * FROM emp;
 id | name  | depno | sal  
----+-------+-------+------
  1 | scott |    10 | 4000
  2 | july  |    20 | 3000
(2 rows)

--调用pkg_emp_mgr.emp_res修改员工信息。
gaussdb=# CALL pkg_emp_mgr.emp_res(2, 30, 6000.00);
--查询数据。
gaussdb=# SELECT * FROM emp;
 id | name  | depno | sal  
----+-------+-------+------
  1 | scott |    10 | 4000
  2 | july  |    30 | 6000
(2 rows)

--调用pkg_emp_mgr.emp_del删除员工信息。
gaussdb=# CALL pkg_emp_mgr.emp_del(2);

--查询数据。
gaussdb=# SELECT * FROM emp;
 id | name  | depno | sal  
----+-------+-------+------
  1 | scott |    10 | 4000
(1 row)
--删除包。
gaussdb=# DROP PACKAGE pkg_emp_mgr;
NOTICE:  drop cascades to 3 other objects
DETAIL:  drop cascades to function public.emp_add(integer,character varying,integer,double precision)
drop cascades to function public.emp_del(integer)
drop cascades to function public.emp_res(integer,integer,character varying)
DROP PACKAGE

--删除表。
gaussdb=# DROP TABLE emp;
DROP TABLE

相关文档