Oracle PL/SQL包(package)
一、 什么是PL/SQL包
包就是一个把各种逻辑相关的类型、常量、变量、异常和子程序组合在一起的模式对象。包通常由两个部分组成:包说明和包体,但有时包体是不需要的。包说明(简写为spec)是应用程序接口;它声明了可用的类型、变量、常量、异常、游标和子程序,包体(Body)部分完全定义游标和子程序,并对说明中的内容加以实现。
如下例所示,我们可以认为说明部分是一个可选接口,而包体是一个"黑盒"。我们可以调试、增强或替换一个包体而不同改变接口(包说明)。
我们可以从SQL*Plus中使用CREATE PACKAGE语句来创建一个包。语法如下:
CREATE [OR REPLACE] PACKAGE package_name
  [AUTHID {CURRENT_USER | DEFINER}]
  {IS | AS}
  [PRAGMA SERIALLY_REUSABLE;]
  [collection_type_definition ...]
  [record_type_definition ...]
  [subtype_definition ...]
  [collection_declaration ...]
  [constant_declaration ...]
  [exception_declaration ...]
  [object_declaration ...]
  [record_declaration ...]
  [variable_declaration ...]
  [cursor_spec ...]
  [function_spec ...]
  [procedure_spec ...]
  [call_spec ...]
  [PRAGMA RESTRICT_REFERENCES(assertions) ...]
END [package_name];
[CREATE [OR REPLACE] PACKAGE BODY package_name {IS | AS}
  [PRAGMA SERIALLY_REUSABLE;]
  [collection_type_definition ...]
  [record_type_definition ...]
  [subtype_definition ...]
  [collection_declaration ...]
  [constant_declaration ...]
  [exception_declaration ...]
  [object_declaration ...]
  [record_declaration ...]
  [variable_declaration ...]
  [cursor_body ...]
  [function_spec ...]
  [procedure_spec ...]
  [call_spec ...]
[BEGIN
  sequence_of_statements]
END [package_name];]
在包说明部分声明的内容都是公有的,对应用程序是可见的。我们必须在所有的其他内容(除了用于为一个特殊的函数命名的编译指示;这样的编译指示必须跟在函数说明之后)声明之后才可以声明子程序。
包体中的内容有私有的,它实现了说明部分定义的细节内容,并且对应用程序是不可见的。紧跟着包体声明部分的是一个可选的初始化部分,它用于初始化包中的变量等。
AUTHID语句决定了是否是所有的打包子程序都按定义者权限(默认)或调用者权限执行,其中涉及到的模式对象是在定义者的模式中解析还是在调用者的模式中解析。
一个调用说明能让我们在Oracle数据词典中发布一个Java方法或外部C函数。调用说明靠把程序的名称、参数类型和返回类型映射到它们的SQL副本(SQL counterpart)中来发布程序。
1、 PL/SQL包举例
在下面的例子中,我们把一个记录类型、游标和两个employment过程进行打包。要注意,过程hire_employee使用数据库序列empno_seq和函数SYSDATE分别插入到字段雇员编号和雇佣日期。
sql包含哪几个部分
CREATE OR REPLACE PACKAGE emp_actions AS  -- spec
  TYPE emprectyp IS RECORD(
    emp_id  INT,
    salary  REAL
  );
  CURSOR desc_salary RETURN emprectyp;
  PROCEDURE hire_employee(
    ename    VARCHAR2,
    job      VARCHAR2,
    mgr      NUMBER,
    sal      NUMBER,
    comm    NUMBER,
    deptno  NUMBER
  );
  PROCEDURE fire_employee(emp_id NUMBER);
END emp_actions;
CREATE OR REPLACE PACKAGE BODY emp_actions AS  -- body
  CURSOR desc_salary RETURN emprectyp IS
    SELECT  empno, sal
        FROM emp
    ORDER BY sal DESC;
  PROCEDURE hire_employee(
    ename    VARCHAR2,
    job      VARCHAR2,
    mgr      NUMBER,
    sal      NUMBER,
    comm    NUMBER,
    deptno  NUMBER
  ) IS
  BEGIN
    INSERT INTO emp
        VALUES (empno_seq.NEXTVAL,
                ename,
                job,
                mgr,
                SYSDATE,
                sal,
                comm,
                deptno);
  END hire_employee;
  PROCEDURE fire_employee(emp_id NUMBER) IS
  BEGIN
    DELETE FROM emp
          WHERE empno = emp_id;
  END fire_employee;
END emp_actions;
只有在包说明部分的声明内容对应用程序才是可见可访问的;包体的详细实现是不可见不可访问的。所以,我们可以在不重新编译调用程序的前提下修改包体(实现)。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。