定义新的包正文。

语法

CREATE [ OR REPLACE ] PACKAGE BODY name
{ IS | AS }
  [ declaration; ] [, ...]
  [ { PROCEDURE proc_name
      [ (argname [ IN | IN OUT | OUT ] argtype [ DEFAULT value ]
        [, ...]) ]
      [ STRICT ]
      [ LEAKPROOF ]
      [ PARALLEL { UNSAFE | RESTRICTED | SAFE } ]
      [ COST execution_cost ]
      [ ROWS result_rows ]
      [ SET config_param { TO value | = value | FROM CURRENT } ]
    { IS | AS }
        program_body
      END [ proc_name ];
    |
      FUNCTION func_name
      [ (argname [ IN | IN OUT | OUT ] argtype [ DEFAULT value ]
        [, ...]) ]
      RETURN rettype [ DETERMINISTIC ]
      [ STRICT ]
      [ LEAKPROOF ]
      [ PARALLEL { UNSAFE | RESTRICTED | SAFE } ]
      [ COST execution_cost ]
      [ ROWS result_rows ]
      [ SET config_param { TO value | = value | FROM CURRENT } ]
    { IS | AS }
        program_body
      END [ func_name ];
    }
  ] [, ...]
  [ BEGIN
      statement; [, ...] ]
  END [ name ]

说明

CREATE PACKAGE BODY 定义新的包正文。CREATE OR REPLACEPACKAGE BODY 将创建新的包正文,或者替换现有正文。

如果包括 schema 名称,则在指定的 schema 中创建包正文。否则在当前 schema 中创建。新的包正文的名称必须与相同 schema 中的现有包规格匹配。在同一个 schema 中,新的包正文名称不能匹配任何现有包正文,除非其目的是更新现有包正文的定义,在这种情况下使用 CREATE OR REPLACE PACKAGE BODY

参数

参数说明
name要创建的包正文的名称(可能是 schema 限定的)。
declaration私有变量、类型、游标或 REF CURSOR 声明。
proc_name公共存储过程或私有存储过程的名称。如果包规格中存在具有相同签名的 proc_name,则它为公共,否则为私有。
argname参数的名称。
IN | IN OUT | OUT参数模式。
argtype程序的参数的数据类型。
DEFAULT value输入参数的默认值。
STRICTSTRICT 关键字指定在使用 NULL 参数调用函数时将不执行函数;相反,函数将返回 NULL。
LEAKPROOFLEAKPROOF 关键字指定除了返回值之外,函数不会公开有关参数的任何信息。
PARALLEL { UNSAFE | RESTRICTED | SAFE }通过 PARALLEL 子句可以使用并行顺序扫描(并行模式)。在查询期间,相比串行顺序扫描,并行顺序扫描使用多个工作线程并行扫描一个关系。
  • 设置为 UNSAFE 时,存储过程或函数不能以并行模式执行。存在此类存储过程或函数时,会强制执行串行执行计划。如果省略 PARALLEL 子句,则这是默认设置。
  • 设置为 RESTRICTED 时,存储过程或函数可以按并行模式执行,但执行限制为并行组中的前几个。如果任何特定关系的限定条件具有存在并行限制的任何内容,则不会为并行执行选择该关系。
  • 设置为 SAFE 时,存储过程或函数可以按并行模式执行,没有任何限制。
execution_costexecution_cost 指定一个正数,提供函数的估计执行成本,单位为 cpu_operator_cost。如果函数返回一个集合,则这是每个返回行的成本。默认值为 0.0025。
result_rowsresult_rows 是查询计划程序预计函数返回的估计行数。默认值为 1000。
SET使用 SET 子句可以为函数的持续时间指定参数值:
  • config_param 指定参数名称。
  • value 指定参数值。
  • FROM CURRENT 确保在函数结束时还原参数值。
program_body构成函数或存储过程的主体的 pragma、声明和 SPL 语句。

Pragma 可以为 PRAGMA AUTONOMOUS_TRANSACTION,这会将函数或存储过程设置为自治事务。

声明可以包括变量、类型、REF CURSOR 或子程序声明。如果包括子程序声明,则它们必须在所有其他变量、类型和 REF CURSOR 声明之后。

func_name公共函数或私有函数的名称。如果包规格中存在具有相同签名的 func_name,则它为公共,否则为私有。
rettype返回数据类型。
DETERMINISTIC包括 DETERMINISTIC 以指定在提供相同参数值时,函数将始终返回相同结果。DETERMINISTIC 函数不可修改数据库。
说明
  • DETERMINISTIC 关键字等同于 PostgreSQL IMMUTABLE 选项。
  • 如果在包正文中为公共函数指定了 DETERMINISTIC,则还必须在包规格中为函数声明指定该关键字。对于私有函数,包规格中没有函数声明。
statement一个 SPL 程序语句。首次引用包时,包初始化部分中的语句会对每个会话执行一次。
说明 STRICTLEAKPROOFPARALLELCOSTROWSSET 关键字可以为PolarDB PostgreSQL版(兼容Oracle)提供扩展功能,但 Oracle 不支持这些关键字。

示例

下面是 empinfo 包的包正文。

CREATE OR REPLACE PACKAGE BODY empinfo
IS
    v_counter       INTEGER;
    PROCEDURE get_name (
        p_empno     NUMBER
    )
    IS
    BEGIN
        SELECT ename INTO emp_name FROM emp WHERE empno = p_empno;
        v_counter := v_counter + 1;
    END;
    FUNCTION display_counter
    RETURN INTEGER
    IS
    BEGIN
        RETURN v_counter;
    END;
BEGIN
    v_counter := 0;
    DBMS_OUTPUT.PUT_LINE('Initialized counter');
END;

以下两个匿名块执行 empinfo 包中的存储过程和函数并显示公共变量。

BEGIN
    empinfo.get_name(7369);
    DBMS_OUTPUT.PUT_LINE('Employee Name    : ' || empinfo.emp_name);
    DBMS_OUTPUT.PUT_LINE('Number of queries: ' || empinfo.display_counter);
END;

已初始化计数器
员工姓名:SMITH
查询数:1

BEGIN
    empinfo.get_name(7900);
    DBMS_OUTPUT.PUT_LINE('Employee Name    : ' || empinfo.emp_name);
    DBMS_OUTPUT.PUT_LINE('Number of queries: ' || empinfo.display_counter);
END;

员工姓名:JAMES
查询数:2