Packages en PL/SQL

    Un paquete es una estructura que agrupa objetos de PL/SQL compilados(procedures, funciones, variables, tipos ...) en la base de datos. Esto nos permite agrupar la funcionalidad de los procesos en programas.

    Lo primero que debemos tener en cuenta es que los paquetes están formados por dos partes: la especificación y el cuerpo. La especificación del un paquete y su cuerpo se crean por separado.

    La especificación es la interfaz con las aplicaciones. En ella es posible declarar los tipos, variables, constantes, excepciones, cursores y subprogramas disponibles para su uso posterior desde fuera del paquete. En la especificación del paquete sólo se declaran los objetos (procedures, funciones, variables ...), no se implementa el código. Los objetos declarados en la especificación del paquete son accesibles desde fuera del paquete por otro script de PL/SQL o programa. Haciendo una analogía con el mundo de C, la especificación es como el archivo de cabecera de un programa en C.  

    Para crear la especificación de un paquete la sintaxis general es la siguiente:


CREATE [OR REPLACE] PACKAGE <pkgName>
IS
  
  -- Declaraciones de tipos y registros públicas
  {[TYPE <TypeName> IS <Datatype>;]}
 
  -- Declaraciones de variables y constantes publicas
-- También podemos declarar cursores

  {[<ConstantName> CONSTANT <Datatype> := <valor>;]} 
  {[<VariableName> <Datatype>;]}
  -- Declaraciones de procedimientos y funciones públicas

  {[FUNCTION <FunctionName>(<Parameter> <Datatype>,...)
RETURN <Datatype>;]}
{[PROCEDURE <ProcedureName>(<Parameter> <Datatype>, ...);]}
END <pkgName>;

    El cuerpo el laimplementación del paquete. El cuerpo del paquete debe implementar lo que se declaró inicialmente en la especificación. Es el donde debemos escribir el código de los subprogramas. En el cuerpo de un package podemos declarar nuevos subprogramas y tipos, pero estos seran privados para el propio package.  

    La sintaxis general para crear el cuerpo de un paquete es muy parecida a la de la especificación, tan solo se añade la palabra clave BODY, y se implementa el código de los subprogramas.


CREATE
[OR REPLACE] PACKAGE BODY <pkgName>
IS
  
  -- Declaraciones de tipos y registros privados
  {[TYPE <TypeName> IS <Datatype>;]}
 
  -- Declaraciones de variables y constantes privadas
-- También podemos declarar cursores

  {[<ConstantName> CONSTANT <Datatype> := <valor>;]} 
  {[<VariableName> <Datatype>;]}
  -- Implementacion de procedimientos y funciones 
  FUNCTION <FunctionName>(<Parameter> <Datatype>,...)
RETURN <Datatype>
  IS
    -- Variables locales de la funcion
  BEGIN
    -- Implementeacion de la funcion
    return(<Result>);
  [EXCEPTION]
    -- Control de excepciones
  END;
 
  PROCEDURE <ProcedureName>(<Parameter> <Datatype>, ...)
  IS
   -- Variables locales de la funcion
  BEGIN
    -- Implementacion de procedimiento
  [EXCEPTION]
    -- Control de excepciones
  END;
END <pkgName>;

    El siguiente ejemplo crea un paquete llamado PKG_CONTABILIDAD.

    Para crear la especificación del paquete:


CREATE OR REPLACE PACKAGE PKG_CONTABILIDAD
IS
  
  -- Declaraciones de tipos y registros públicas
  TYPE Cuenta_contable IS RECORD
  (
    codigo_cuenta VARCHAR2(6),
    naturaleza    VARCHAR2(2) ,
    actividad     VARCHAR2(4) ,
    debe_haber    VARCHAR2(1)
  );
 
  -- Declaraciones de variables y constantes publicas
  DEBE CONSTANT VARCHAR2(1) := 'D';
  HABER CONSTANT VARCHAR2(1) := 'D';
ERROR_CONTABILIZAR EXCEPTION;
  -- Declaraciones de procedimientos y funciones públicas
  PROCEDURE Contabilizar (mes VARCHAR2) ;
  FUNCTION  fn_Obtener_Saldo(codigo_cuenta VARCHAR2) RETURN NUMBER;
END PKG_CONTABILIDAD;

    Aquí  sólo hemos declarado las variables y constantes, prototipado las funciones y procedimientos públicos . Es en el cuerpo del paquete cuando escribimos el código de los subprogramas Contabilizar y fn_Obtener_Saldo.


CREATE PACKAGE BODY PKG_CONTABILIDAD IS
 FUNCTION fn_Obtener_Saldo(codigo_cuenta VARCHAR2) 
 RETURN NUMBER
 IS
   saldo NUMBER;
 BEGIN
  SELECT SALDO INTO saldo
        FROM SALDOS
        WHERE CO_CUENTA = codigo_cuenta;
  return (saldo);
 END;
 
 PROCEDURE Contabilizar(mes VARCHAR2)
 IS
   CURSOR cDatos(vmes VARCHAR2)
   IS
   SELECT *
   FROM FACTURACION
   WHERE FX_FACTURACION = vmes
AND PENDIENTE_CONTABILIZAR = 'S';
 
   fila cDatos%ROWTYPE;
 
 BEGIN
   OPEN cDatos(mes);
     LOOP FETCH cDatos INTO fila;
     EXIT WHEN cDatos%NOTFOUND;
     /* Procesamiento de los registros recuperados */
     END LOOP;
   CLOSE cDatos;
 
 EXCEPTION
 WHEN OTHERS THEN
RAISE ERROR_CONTABILIZAR;
 END Contabilizar;
END PKG_CONTABILIDAD; 

    Es posible modificar el cuerpo de un paquete sin necesidad de alterar por ello la especificación del mismo.

    Los paquetes pueden llegar a ser programas muy complejos y suelen almacenar gran parte de la lógica de negocio.

 

 

Pedro  Herrarte  Sánchez
Paquetes en PL/SQL
Pedro Herrarte Sánchez

Pedro Herrarte, es consultor independiente, ofreciendo servicios de consultoría, análisis, desarrollo y formación. Posee mas de diez años de experiencia trabajando para las principales empresas de España. Es especialista en tecnologías .NET, entornos Web (ASP.NET, ASP.NET MVC,jQuery, HTML5), bases de datos (SQL Server y ORACLE) e integración de sistemas. Es experto en desarrollo (C#, VB.Net, T-SQL, PL/SQL, , ASP, CGI , C, Pro*C, Java, Essbase, Vignette, PowerBuilder y Visual Basic ...) y bases de datos (SQL Server y ORACLE). Pedro es MCP y MAP 2012, es fundador, diseñador y programador de www.devjoker.com..
Fecha de alta:13/07/2006
Última actualizacion:13/07/2006
Visitas totales:186129
Valorar el contenido:
Últimas consultas realizadas en los foros
Últimas preguntas sin contestar en los foros de devjoker.com