ITPub博客

首页 > 数据库 > 国内数据库 > 南大通用GBase 8s兼容PLSQL之PACKAGE包

南大通用GBase 8s兼容PLSQL之PACKAGE包

原创 国内数据库 作者:CallMeJasonGao 时间:2021-05-21 15:56:49 0 删除 编辑

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

南大通用在 GBase 8s 中兼容 ORACLE 的包及相关 PL/SQL 程序设计元素。

1、      包的创建

一个 PL/SQL 包由如下两部分组成:包头,或称为包的规范:主要是包的一些定义信息,不包含具体的代码实现部分,也可以说包头是 PL/SQL 程序和其他应用程序的接口,包含子程序、变量、常量、类型、游标和异常的声明。包体:是对包规范中声明的子程序和游标的实现部分,包体的内容对于外部应用程序来说是不可见的,包体就像是一个黑匣子一样,是对包规范的实现。注意:包头中子程序和游标是需要实现部分的,如果包头中没有声明子程序或游标,则包体就不是必须的。

2、      包的删除

DROP PACKAGE 会将包头和包体一并删除,也可以通过 DROP PACKAGE BODY 关键字只删除包体,此时包头依然有效。

3、      包的引用

包在首次引用时实例化并执行 initialize_section 部分,包为 SESSION 级,即多 SESSION 之间是不同的包实例。

下面我们通过几个例子示范包的常见用法,注意需要将 SQLMODE 设置为 ’ORACLE’ ,如果需要输出请设置 SERVEROUTPUT 为 ON 。

SET ENVIRONMENT   SQLMODE 'ORACLE';

SET SERVEROUTPUT ON;

例子 1 :包中变量和常量的声明

CREATE PACKAGE   pkg_demo1 AS

  companyName   CONSTANT VARCHAR(100) := 'GBASE';

  productName   VARCHAR(100);

END;

本例子中,只有包头,并不需要包体。注意,常量不能使用变量赋初始值。然后我们创建一个过程,对包中声明的常量进行引用,包中的变量可以赋值和引用。

CREATE PROCEDURE   p_demo1 AS

BEGIN

    DBMS_OUTPUT.PUT_LINE(pkg_demo1.companyName);

    pkg_demo1.productName := 'GBase 8s';

    DBMS_OUTPUT.PUT_LINE(pkg_demo1. productName);

END;

通过如下代码进行过程的调用。

CALL PROCEDURE   p_demo1();

可以看到如下结果。

GBASE

GBase 8s

例子 2 :包中过程和函数的用法

CREATE PACKAGE   pkg_demo2 AS

  PROCEDURE   helloWorld;

  FUNCTION   myPlus(param1 IN INT, param2 IN INT) RETURN INT;

END;

然后我们创建包体,用于实现包头中声明的过程和函数。

CREATE PACKAGE BODY   pkg_demo2 AS

  PROCEDURE   helloWorld AS

  BEGIN

      DBMS_OUTPUT.PUT_LINE('HelloWorld!');

  END;

  FUNCTION   myPlus (param1 IN INT, param2 IN INT) RETURN INT AS

  BEGIN

    RETURN   param1 + param2;

    EXCEPTION

      WHEN   OTHERS THEN DBMS_OUTPUT.PUT_LINE('error');

  END;

END;

我们创建一个过程,对包中声明的过程和函数进行引用。

CR EATE PROCEDURE p_demo2 AS

BEGIN

    pkg_demo2.helloWorld;

    DBMS_OUTPUT.PUT_LINE(pkg_demo2.myPlus (2, 3));

END;

通过如下代码进行过程的调用。

CALL PROCEDURE   p_demo2();

可以看到如下结果。

HelloWorld!

5

例子 3 :包的状态

CREATE PACKAGE   pkg_demo3 AS

  PROCEDURE   getCount;

END;

 

CREATE PACKAGE BODY pkg_demo3 AS

  FCount   INTEGER;

  PROCEDURE   getCount AS

  BEGIN

      DBMS_OUTPUT.PUT_LINE('Current count is:');

      DBMS_OUTPUT.PUT_LINE(FCount);

    FCount:=   FCount + 1;

  END;

BEGIN

  FCount :=   1;

END;

在上面的例子中, pkg_demo3 在包头中声明了一个名称为 getCount 的过程,然后包体中声明了一个类型为 INTEGER 的私有变量,并对包头中声明的 getCount 过程进行了代码实现, getCount 过程实现输出私有变量 FCount 的值,并每次对 Fcount 进行 +1 操作。由于包是 SESSION 级的,因此我们可以看到在 call pkg_demo3.getCount() 多次引用时返回值会发生变化:第一次引用时输出的是 1 ,第二次引用时输出的是 2 ,第三次引用时输出的是 3 。特别注意的是此时如果另一个 SESSION 中引用 pkg_demo3 ,输出的不是 4 而是 1 ,即多 SESSION 之间是不同的包实例。

例子 4 :通过包中游标对数据进行遍历

为了演示这个例子,我们需要创建一张包含 2 个字段的表。

CREATE TABLE   TPERSON(

  FID   VARCHAR(10) NOT NULL PRIMARY KEY,

  FName   VARCHAR(50)

)

并准备几条数据。

INSERT INTO TPERSON   VALUES('1', 'first');

INSERT INTO TPERSON VALUES('2', 'second');

INSERT INTO TPERSON VALUES('3', 'third');

创建包头,包含一个整型的变量和一个返回类型是 TPERSON 表行记录类型的游标声明。

CREATE PACKAGE   pkg_demo4 AS

  CURSOR myc   RETURN TPERSON%ROWTYPE;

END;

创建包体,可以看到包体中对游标进行了代码实现。这里需要补充说明两点:一是包的实现部分也可以写在包头中,从而不创建包体,建议的方式是将游标的代码写在包体里,将定义和实现进行分离;二是对游标的 OPEN 、 FETCH 、 CLOSE 等操作一般建议写在调用包游标的地方。

CREATE PACKAGE BODY   pkg _ demo4 AS

  CURSOR myc   RETURN TPERSON%ROWTYPE IS SELECT FID, FName FROM TPERSON;

END;

然后我们创建一个过程,在过程中,通过 TYPE 定义了一个记录类型 TR ,并声明了一个类型为 TR 的 mt 变量。在过程的实现部分,首先通过 OPEN 打开了游标,然后遍历取数据并赋值给 mt ,并通过内置包 DBMS_OUTPUT 的 PUT 方法和 PUT_LINE 方法进行输出。

CREATE PROCEDURE   p_demo4 AS

  TYPE TR IS   RECORD(

    id   VARCHAR(10),

    name   VARCHAR(50)

  );

  mt TR;

BEGIN

  OPEN   pkg_demo4.myc;

  FETCH   pkg_demo4.myc INTO mt;

  WHILE   pkg_demo4.myc%FOUND LOOP   

      DBMS_OUTPUT.PUT(mt.id);

      DBMS_OUTPUT.PUT(': ');

      DBMS_OUTPUT.PUT_LINE(mt.name);

    FETCH   pkg_demo4.myc INTO mt;

  END LOOP;

  CLOSE   pkg_demo4.myc;

END;

最后我们通过如下代码进行过程的调用

CALL PROCEDURE   p_demo4();

可以看到如下结果

1: first

2: second

3: third

 


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69980453/viewspace-2773350/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2020-09-28

  • 博文量
    7
  • 访问量
    5384