首批通过分布式安全可靠测评,为关键业务系统打造
创建程序包
更新时间:2026-03-28 11:51:11
程序包由包头(PACKAGE SPECIFICATION)和包主体(PACKAGE BODY)两个部分组成,同时程序包的定义分为程序包头定义和程序包主体定义。
功能适用性
该内容仅适用于 OceanBase 数据库企业版。OceanBase 数据库社区版暂不支持。
包头(PACKAGE SPECIFICATION)部分声明包内数据类型、变量、常量、游标、子程序和异常错误处理等元素,这些元素为包的公有元素;包主体(PACKAGE BODY)则是包头部分的具体实现,它定义了包头部分所声明的游标和程序,在包主体中还可以声明包的私有元素。
包头和包主体分开编译,并作为两个分开的对象存放在数据库字典视图 USER_SOURCE、 ALL_SOURCE 和 DBA_SOURCE 中。
创建包
创建包头的语法如下:
CREATE [OR REPLACE] PACKAGE package_name
[AUTHID {CURRENT_USER | DEFINER}]
{IS | AS}
[public_type_declarations[public_type_declarations]...]
[public_cursor_declarations[public_cursor_declarations]...]
[public_variable_declarations[public_variable_declarations]...]
[function_declarations[function_declarations]...]
[procedure_specifications[procedure_specifications]...]
END [package_name]
其中,AUTHID CURRENT_USER 和 AUTHID DEFINER 选项说明应用程序在调用函数时所使用的权限模式。
创建包主体定义的语法如下:
CREATE [OR REPLACE] PACKAGE BODY package_name
{AS|IS}
[private_type_declarations[private_type_declarations]...]
[private_variable_declarations[private_variable_declarations]...]
[private_function_declarations[function_declarations]...]
[private_procedure_specifications[procedure_specifications]...]
[public_cursor_declarations[public_cursor_declarations]...]
[public_function_declarations[function_declarations]...]
[public_procedure_specifications[procedure_specifications]...]
BEGIN
PL Statement
END [package_name]
示例
如下示例中,创建的程序包名称为 obdemo_pack,该程序包中包含一个记录变量 obDeptRec、两个函数和一个存储过程。
obclient> CREATE TABLE obdept(
deptno NUMBER(10,0),
dname VARCHAR(15),
loc VARCHAR(20)
);
Query OK, 0 rows affected
obclient> CREATE OR REPLACE PACKAGE obdemo_pack
IS
obDeptRec obdept %ROWTYPE;
FUNCTION add_obdept(dept_no NUMBER, dept_name VARCHAR2, location VARCHAR2)
RETURN NUMBER;
FUNCTION remove_obdept(dept_no NUMBER)
RETURN NUMBER;
PROCEDURE query_obdept(dept_no IN NUMBER);
END obdemo_pack;
/
Query OK, 0 rows affected
如下示例中,包主体的创建方法实现了所声明的包头:
obclient> CREATE OR REPLACE PACKAGE BODY obdemo_pack
IS
FUNCTION add_obdept(dept_no NUMBER, dept_name VARCHAR2, location VARCHAR2)
RETURN NUMBER
IS
deptno_remaining EXCEPTION;
PRAGMA EXCEPTION_INIT(deptno_remaining, -1); -- -1 是违反唯一约束条件的错误代码
BEGIN
INSERT INTO obdept VALUES(dept_no, dept_name, location);
IF SQL%FOUND THEN
RETURN 1;
END IF;
EXCEPTION
WHEN deptno_remaining THEN
RETURN 0;
WHEN OTHERS THEN
RETURN -1;
END add_obdept;
FUNCTION remove_obdept(dept_no NUMBER)
RETURN NUMBER
IS
BEGIN
DELETE FROM obdept WHERE deptno=dept_no;
IF SQL%FOUND THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
EXCEPTION
WHEN OTHERS THEN
RETURN -1;
END remove_obdept;
PROCEDURE query_obdept (dept_no IN NUMBER)
IS
BEGIN
SELECT * INTO obDeptRec FROM obdept WHERE deptno=dept_no;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('数据库中没有编码为'||dept_no||'的部门');
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('程序运行错误!');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLCODE||'----'||SQLERRM);
END query_obdept;
BEGIN
Null;
END obdemo_pack;
/
Query OK, 0 rows affected
在 OceanBase 数据库中,程序包还支持创建同义词,示例如下:
obclient> CREATE OR REPLACE SYNONYM syn_pag FOR obdemo_pack;
Query OK, 0 rows affected
obclient> CALL syn_pag.query_obdept('123');
Query OK, 0 rows affected
调用程序包的函数和方法
调用程序包里面的变量、常量、函数、方法等需要在对象名里包含包的名字,并用"."分隔。即对程序包内共有元素的调用格式为: 包名.元素名称。
如下示例中,调用 obdemo_pack 程序包内函数对 obdept 表进行插入、查询和修改操作,并通过 obdemo_pack 程序包中的记录变量 obDeptRec 显示所查询到的数据库信息:
obclient> DECLARE
Var NUMBER;
BEGIN
Var := obdemo_pack.add_obdept(900,'Administration', 'Beijing');
IF var =-1 THEN
DBMS_OUTPUT.PUT_LINE(SQLCODE||'----'||SQLERRM);
ELSIF var =0 THEN
DBMS_OUTPUT.PUT_LINE('该部门记录已经存在!');
ELSE
DBMS_OUTPUT.PUT_LINE('添加记录成功!');
obdemo_pack.query_obdept(900);
DBMS_OUTPUT.PUT_LINE(obdemo_pack.obDeptRec.deptno||'---'||obdemo_pack.obDeptRec.dname||'---'||obdemo_pack.obDeptRec.loc);
var := obdemo_pack.remove_obdept(900);
IF var =-1 THEN
DBMS_OUTPUT.PUT_LINE(SQLCODE||'----'||SQLERRM);
ELSIF var=0 THEN
DBMS_OUTPUT.PUT_LINE('该部门记录不存在!');
ELSE
DBMS_OUTPUT.PUT_LINE('删除记录成功!');
END IF;
END IF;
END;
/
Query OK, 0 rows affected
添加记录成功!
900---Administration---Beijing
删除记录成功!