GBase新闻

专注于数据库软件产品和服务,致力于成为用户最信赖的数据库产品供应商

包学包会!南大通用GBase 8s数据库“包”的解析

发布时间:2025-03-19

包?什么包?双肩包还是小笼包?

以上都不是,我们说的是数据库“包”。在GBase 8s数据库中,“包”提供了代码封装、信息隐藏和子程序重载等功能,提高了代码的可维护性和可重用性。本文将深入探讨GBase 8s数据库中“包”的概念、创建、使用和删除,帮助大家进一步理解这一内容。

 

包的概念

“包”是一组相关过程、函数、变量、常量、类型、游标和异常等PL/SQL程序设计元素的组合。“包”具有面向对象设计的特点,是对这些PL/SQL程序设计元素的封装。“包”像一个容器或一个命名空间,可以将各种逻辑相关的过程、函数、变量、常量、类型、游标和异常结合在一起,为开发人员编写大型复杂应用程序提供良好的组织单元。当“包”被定义好后,应用程序可以通过“包”来访问各种不同的功能单元,而不用担心过多零散的子程序导致程序代码的松散。“包”具有简化应用设计、提高应用性能、实现信息隐藏、子程序重载等特点。对“包”中涉及的过程、函数、变量、常量、类型、游标和异常等PL/SQL程序设计元素如无特殊约束说明,其用法和现状保持一致。

 

包的创建

“包”由包头和包体组成,包头中主要是包的一些定义信息,包体中则是对应的实现部分,包中的子程序和游标是需要实现部分的,如果包头中没有声明子程序或游标,则包体可以省略。在包头中定义的对象为公有对象,可以在外部调用,只在包体中定义的对象为私有对象,只能在包中使用。

创建包头语法图如下:

item_list_1为定义的对象,包括存储过程、函数、变量、常量、类型、游标和异常。

创建包体语法图如下:

包头声明的变量、常量、游标等,包体只允许初始化一次。

包头声明的游标名不允许与 PROCEDURE、FUNCTION 的例程名相同。

 

包的删除

可以使用drop package body pkg_name单独删除包体,或者使用drop package pkg_name删除包和包体。删除包体后,包头依然有效。

 

包的引用

“包”在首次引用时实例化并执行initialize_section部分,我们通过例子示范包的常见用法,注意需要将SQLMODE设置为’ORACLE’,如果需要输出请设置SERVEROUTPUT为ON。

 

包中对象调用示例

以下用例创建包中包含类型、变量、常量、异常、存储过程、函数、游标。

set environment sqlmode 'oracle';
set serveroutput on;
/**********************************************
*类型 type_1
*游标 cur_1
*异常 err
*函数 sub:实现两个整数减法
*过程 add_1:实现两个整数加法
*        add_2:调用cur_1和add_1,实现将t1表中的两列相加,返回结果
*        p_1:调用常量、变量、函数sub
*        p_2:实现修改表tint的值(配合add_1使用)
**********************************************/
/********1.测试准备********/
drop table if exists tint;
create table tint(id int,val1 int,val2 int);   --扩充数据
insert into tint values(1,10,1);
insert into tint values(2,20,2);
insert into tint values(3,30,3);
insert into tint values(4,40,4);
insert into tint values(5,50,5);
insert into tint values(6,60,6);
insert into tint values(7,70,7);
insert into tint values(8,80,8);
insert into tint values(9,90,9);

/********2.包的创建********/
--创建包头
create package all_object as
--1.变量、常量
     v_1 int;
     v_2 int;
     v_3 int:=1;
     c_1 constant varchar2(100):='常量测试';
--2.异常no_res
     err EXCEPTION;
--3.函数sub,实现两个整数减法
     function sub(a in int,b in int,c out int) return int;
--4.游标cur_1
     cursor cur_1 return tint%rowtype;
--5.存储过程add_1,实现两个整数加法
     procedure add_1(a in int,b in int,c out int);
--6.存储过程add_2,调用游标cur_1和存储过程add_1,实现将t1表中的两列相加,返回结果
     procedure add_2(d int);
--7.存储过程p_1,调用变量、常量、异常、函数
     procedure p_1;
--8.存储过程,对表中数据进行修改
     procedure p_2(a int,b int,c int);
end all_object;
/

--创建包体
create package body all_object as
--4.创建游标
     cursor cur_1 return tint%rowtype is select id,val1,val2 from tint;
--3.创建函数sub,实现两个整数减法
     function sub(a in int,b in int,c out int) return int is
     begin
            if(a>b) then
                   c:=a-b;
            else
                   raise err;
            end if;
            return 0;

                         exception
            when err then dbms_output.put_line('a < b');
     end;
--5.存储过程add_1,实现两个整数加法
     procedure add_1(a in int,b in int,c out int) is
     begin
            c:=a+b;
     end;
--6.存储过程add_2,实现两个整数加法
     procedure add_2(d int) as
     type type_1 is record(
      v0 int,
            v1 int,
            v2 int
);
     ty_1 type_1;
     v3 int;
     begin
     open cur_1;
     for i in 1..d loop
            fetch cur_1 into ty_1;
            add_1(ty_1.v1,ty_1.v2,v3);
            dbms_output.put_line(i||' is:'||v3);
     end loop; 
     close cur_1;
     end;
--7.存储过程p_1,调用变量、常量、函数
     procedure p_1 as
     v_4 int;
     begin
            all_object.v_1:=100;
            all_object.v_2:=20;
            v_4:=sub(v_1,v_2,v_3);
            dbms_output.put_line(v_1||' - '||v_2||' = '||v_3);
            dbms_output.put_line('constant c_1 is :'||all_object.c_1);
     end;
--8.存储过程,对表中数据进行修改
     procedure p_2(a int,b int,c int) as
     begin
     update tint set val1=a,val2=b where id=c;
     end;
end all_object;
/
/********3.包中对象调用********/
--修改表tint中id为1的数据为100,50
call all_object.p_2(100,50,1);
--将表tint中2、3列值相加,并返回结果,3代表取前3个结果
call all_object.add_2(3);
--实现两个变量相减,并返回结果;调用公有常量并返回结果
call all_object.p_1();

/********4.清理环境********/
drop package all_object;
drop table tint;

执行结果:

> call all_object.p_2(100,50,1);
Routine executed.
> call all_object.add_2(3);
Routine executed.
1 is:150
2 is:22
3 is:33
> call all_object.p_1();
Routine executed.
100 - 20 = 80
constant c_1 is :常量测试

看到这里,大家了解数据库“包”了吗?

我们希望这篇文章能够让大家更好地理解和使用GBase 8s数据库中的“包”,为数据库开发提供助力。如果对GBase 8s数据库的“包”存在任何疑问或想要解锁更多GBase数据库的技术知识,欢迎大家到GBASE技术社区(www.gbase.cn)分享、交流。