包(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