InicioArticulos y noticiasBases de datosProgramaciónForosInternetServiciosContratacionEmail
Tutorial PL/SQL
Introducción a PLSQL
Programación con PL/SQL
Fundamentos de PL/SQL
Tipos de datos en PL/SQL
Operadores en PL/SQL
Estructuras de control en PL/SQL
Bloques PL/SQL
Cursores en PL/SQL
Cursores Implicitos en PL/SQL
Cursores Explicitos en PL/SQL
Cursores de actualización en PL/SQL
Excepciones en PL/SQL
Excepciones personalizadas en PL/SQL
Propagacion de excepciones en PL/SQL
Subprogramas en PL/SQL
Procedimientos almacenados en PL/SQL
Funciones en PL/SQL
Triggers en PL/SQL
Subprogramas en bloques anónimos
Paquetes en PL/SQL
Registros PL/SQL
Tablas PL/SQL
Tipo VARRAY
BULK COLLECT
Transacciones con PL/SQL
Transacciones autónomas
SQL Dinamico
Funciones integradas de PL/SQL
Secuencias
PL/SQL y Java
También puedes ver ...
Excepciones personalizadas en PL/SQL
Como conectar a ORACLE con Java
Recuperar datos BLOB de ORACLE
Trabajar con datos de tipo BLOB en ORACLE
PL/SQL y Java
Secuencias
Transacciones autónomas
SQL Dinamico
Funciones integradas de PL/SQL
Transacciones con PL/SQL


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.

 

 


Inicio | Tutorial PL/SQL Subprogramas en bloques anónimosTutorial PL/SQLRegistros PL/SQL Versión para imprimir Foros de consulta

 
posible error por Edu
Respuesta recibida el [26/07/2007 12:14:34]
Buenos dias, solo queria comentar una cosilla, en la función fn_Obtener_Saldo no se debería devolver saldo_cta en lugar de saldo?

Perdon por las molestias.

 
Si señor ... tiene toda la raz... por Devjoker
Respuesta recibida el [26/07/2007 11:01:01]
Si señor ... tiene toda la razón.
Ya está corregido.

 
Buenas, estaria piola comentar... por MaRtO
Respuesta recibida el [23/10/2007 02:04:18]
Buenas, estaria piola comentar como llamar a ejecutar a los package desde un PL. O quizas esta en algun lado y no lo encontré ( desastre lo mio )

 
Es muy bueno por Andres
Respuesta recibida el [26/10/2007 01:29:06]
Es muy bueno el tutorial y a las personas que no tenemos mucho conocimiento en PL/SQL nos ayuda mucho.

aahh! creo que la linea
DEBE CONSTANT VARCHAR2(1) := 'D'; HABER CONSTANT VARCHAR2(1) := 'D';
deberia ir
DEBE CONSTANT VARCHAR2(1) := 'D'; HABER CONSTANT VARCHAR2(1) := 'H';

 
duda por Irene
Respuesta recibida el [27/11/2007 01:30:54]
Hola, si tegno que hacer un procedimiento que devuelva todos los objetos de una tabla y he declarado un cursor con la select en la cabecera del package, ¿Cómo utilizo ese cursor en el procedimiento? No sé como devolver todas las salidas. ¿sería mejor hacer la select dentro del procedimiento y no declarar ningun cursor?

 
NOOB por yo
Respuesta recibida el [08/01/2008 12:35:15]
 END fn_Obtener_Saldo;

 
R: por TheBest
Respuesta recibida el [08/01/2008 12:57:08]
If you nead help Gutty is your answer.

 
FUCKING SHIT por CaperucitaFeliz
Respuesta recibida el [08/01/2008 12:59:07]
gutty iz a nub lol fuck u

 
Te agradezco por tu ayuda, es ... por Jaime
Respuesta recibida el [11/01/2008 10:15:04]
Te agradezco por tu ayuda, es un tutorial excelente.

 
Super Bueno por Luis Seguel
Respuesta recibida el [27/03/2008 03:46:43]
Super Bueno me Ayudó un Montón

 
genial por carlos
Respuesta recibida el [30/08/2008 09:24:52]
gracias por este tipo de informacion, me sirvio bastante en una exposicion que hice, en esperAa de mas informacion.
muchas gracias

 
sip por Cristian C,
Respuesta recibida el [21/10/2008 10:56:57]
Felicitaciones,.
Yo q no sabia nada, aclaro muchas cosas,, se le felicita siga adelante,

 
Y como se ejecuta el packerte creado? por Milor
Respuesta recibida el [11/12/2008 12:04:47]
Pues eso yo he creado un paquete.... y no tengo ni idea como ejecutarlo.

El paquete en question:

CREATE OR REPLACE
PACKAGE MILOR_PACK
AS
PROCEDURE CREARTABLA
(
nombretabla in VARCHAR2,
nombre1col in VARCHAR2,
tipo1col in VARCHAR2,
nombre2col in VARCHAR2,
tipo2col in VARCHAR2,
nombre3col in VARCHAR2,
tipo3col in VARCHAR2)
END MILOR_PACK;
/

CREATE OR REPLACE
PACKAGE BODY MILOR_PACK
AS
PROCEDURE CREARTABLA
(
nombretabla in VARCHAR2,
nombre1col in VARCHAR2,
tipo1col in VARCHAR2,
nombre2col in VARCHAR2,
tipo2col in VARCHAR2,
nombre3col in VARCHAR2,
tipo3col in VARCHAR2 )
IS
v_id_cursor Number;
v_create VARCHAR2(100);
v_n_rows Number;
BEGIN
v_id_cursor := DBMS_SQL.OPEN_CURSOR;
v_create := 'CREATE TABLE ' || nombretabla || ' ( ' || nombre1col || ' ' || tipo1col || ', ' || nombre2col || ' ' || tipo2col || ', ' || nombre3col || ' ' || tipo3col || ')' ;
DBMS_SQL.PARSE(v_id_cursor, v_create, DBMS_SQL.V7);
v_n_rows := DBMS_SQL.EXECUTE(v_id_cursor);
DBMS_SQL.CLOSE_CURSOR(v_id_cursor);
EXCEPTION
WHEN OTHERS THEN
DBMS_SQL.CLOSE_CURSOR(v_id_cursor);
RAISE;
END CREARTABLA;
END MILOR_PACK;
/

 
Pregunta sobre arreglos de tipo record por Matias
Respuesta recibida el [06/01/2009 11:36:48]
Una pregunta cuando utilizas  como parametros los campos de arreglo de tipo record  no debe ser la siguiente manera 
nombredelrecord.campo
FUNCTION fn_Obtener_Saldo(Cuenta_contable.codigo_cuenta VARCHAR2) RETURN NUMBER;

 
Perfecto por Pedro
Respuesta recibida el [21/01/2009 03:59:25]
Desde un punto de vista objetivo, este gran manual me ha resultado muy util para realizar las funciones que me han encomendado en la empresa en la que estoy ejerciendo actualmente como auxiliar de enfermeria...

gracias, siga así, el sector de la medicina le agradece su trabajo y tiempo empleado.


 
Este gran manual me ha ayudado... por Angel
Respuesta recibida el [21/01/2009 04:05:20]
Este gran manual me ha ayudado bastante a la hora de tener que enterrar todos los cadáveres que mi amigo el enfermero no ha podido curar. Por otro lado, quería agradecer al "especialista" en tecnologías .NET, entornos Web, bases de datos (SQL Server y ORACLE) e integración de sistemas su gran labor en el mundo de la sepultura. 

Un saludo de ultratuuuuuuuuuuuumbaaa!ç



 
por dios que foto por manolo
Respuesta recibida el [22/01/2009 02:42:33]
pero que pedazo de hombre eres pedro herrarte sanchez. wapo, wapo y wapo!!!!!!!!!!!!!!

 
manual por neu
Respuesta recibida el [28/01/2009 09:57:33]
bastante flojito

 
Compartir Memoria por Link81
Respuesta recibida el [10/07/2009 11:07:31]
Que pasa con los datos al momento de que dos procesos acceden al mismo paquete, es decir, en memoria se tiene 2 copias del paquete completo cada uno con sus propios datos? 
El paquete es por sesion iniciada?

 
Compartir Memoria por Link81
Respuesta recibida el [10/07/2009 11:07:37]
Que pasa con los datos al momento de que dos procesos acceden al mismo paquete, es decir, en memoria se tiene 2 copias del paquete completo cada uno con sus propios datos? 
El paquete es por sesion iniciada?

 
como le hago por Eddin
Respuesta recibida el [15/07/2009 06:24:24]
ya cree un paquete pero no se como ejecutarlo.. alguien me puede ayudar... tengo el mismo problema que milor

 
como llamar ha los paketes desde pl/sql por dante
Respuesta recibida el [23/11/2009 09:55:57]
quisiera saber como ejecutar los paquetes o mandalos allamar,
cree uno y pongo la siguinte instruccion :SELECT PROG_TOW.GENERA_ALET FROM DUAL; pero decon otro que hice uso casi lo mismo pero me menda erro cheken: SELECT PROG_TOW.MAXIMO FROM DUAL;
ERROR en línea 1:
ORA-00904: "PROG_TOW"."MAXIMO": identificador no válido

 
Observaciones sobre los packages por Jorge
Respuesta recibida el [31/01/2010 10:53:40]
Falta algo en la sintaxis del package body, que si bien es opcional, es muy útil y es el bloque de inicialización.
Aqui va el ejemplo:
CREATE OR REPLACE PACKAGE BODY Prueba IS

-- Private type declarations
TYPE < Typename > IS < Datatype >;

-- Private constant declarations
< Constantname > CONSTANT < Datatype > := < VALUE >;

-- Private variable declarations
< Variablename > < Datatype >;

-- Function and procedure implementations
FUNCTION < Functionname > (< Parameter > < Datatype >) RETURN < Datatype > IS
< Localvariable > < Datatype >;
BEGIN
< STATEMENT >;
RETURN(< RESULT >);
END;

BEGIN
-- Initialization
< STATEMENT >;
END Prueba;

Este Begin que viene a continuación de los procedimientos y funciones que se hayan definidos, se dispara siempre que el package es invocado, esto nos puede ayudar a inicializar valores de variables globales a nivel package que nos permitirá usarlas a lo largo del mismo evitando que tengamos que recurrir a extrañas artimañas.

 
Observaciones 2 por Jorge
Respuesta recibida el [31/01/2010 11:24:35]
En packages que son creados con el fin de resolver procesos complejos, suelen definirse un gran nro. de funciones y procedimientos que son invocados por una función o procedimiento principal dentro del mismo package. Para evitar tener que declarar cada función o procedimiento en el encabezado del package, los procedimiento y funciones deben ser creadas dentro del body de manera ordenada, es decir veamos un ejemplo sencillo.

CREATE OR REPLACE PACKAGE Prueba IS

PROCEDURE Main;

END Prueba;


/
CREATE OR REPLACE PACKAGE BODY Prueba IS

PROCEDURE Tercera(x NUMBER) IS
a NUMBER := 0;
BEGIN
a := x + 5;
EXCEPTION
WHEN OTHERS THEN
Raise_Application_Error(20003, 'Error en Tercera');
END Tercera;
-----------------------------
PROCEDURE Segunda(x NUMBER) IS
a NUMBER := 0;
BEGIN
a := x * 4;
EXCEPTION
WHEN OTHERS THEN
Raise_Application_Error(20003, 'Error en Segunda');
END Segunda;
-----------------------------
PROCEDURE Primera(x NUMBER) IS
BEGIN
Tercera(x * 3);
EXCEPTION
WHEN OTHERS THEN
Raise_Application_Error(20003, 'Error en Primera');
END Primera;
-----------------------------
PROCEDURE Main IS
n NUMBER := 0;
BEGIN
Primera(n);
Segunda(n);
EXCEPTION
WHEN OTHERS THEN
Raise_Application_Error(20003, 'Error en Main');
END Main;
BEGIN
NULL;
END Prueba;
/

Si se fijan, así como está y sin declarar nada mas que el procedimiento Main, el package compila sin errores, el motivo es la forma que fueron definindos los procedimientos. Estos si miran con cuidado estan en un orden determinado, donde los procedimientos que invocan a otros estan abajo de los invocados, de esa manera el compilador simepre tiene definido al procedimiento invocado cuando le toca compilar al que lo invoca. De esta manera reducimos considerablemente el nro. de procedimientos definidos en la cabecera del package, facilitando la rápida identificación del procedimiento principal y evitando que estén disponibles para todo el mundo aquellos procedimientos o funciones que son solo de uso interno del package


Añadir comentario ... Para preguntar utiliza los foros
Autor:

Título:


Para preguntar utiliza los foros.



Inicio | Tutorial PL/SQL Subprogramas en bloques anónimosTutorial PL/SQLRegistros PL/SQL Versión para imprimir

Paquetes en PL/SQL
Autor: Pedro Herrarte Sánchez
Visitas: 56831 Fecha de publicación: 13/07/2006
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, bases de datos (SQL Server y ORACLE) e integración de sistemas.

Es experto en desarrollo (C#, ASP.NET, 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).

Es fundador, diseñador y programador de www.devjoker.com.




Visitas: 90 | Comentarios: 2 | Archivo: Articulos
02/02/2010 iPad vs Telesketch
Visitas: 794 | Comentarios: 2 | Archivo: Articulos
Categorias: Humor
Visitas: 749 | Comentarios: 3 | Archivo: Articulos
Visitas: 3145 | Comentarios: 2 | Archivo: Articulos
Categorias: C#
Visitas: 14504 | Comentarios: 7 | Archivo: Articulos
Categorias: C#|Seguridad
Visitas: 1478 | Comentarios: 3 | Archivo: Articulos
Visitas: 691 | Comentarios: 2 | Archivo: Articulos
Visitas: 369 | Comentarios: 0 | Archivo: Articulos
Visitas: 2013 | Comentarios: 2 | Archivo: Articulos
Categorias: C#

Útimos temas recibidos en los foros ...
certificado de pensiones del bbva horizonte por danger ... [Actualidad] 123 12/01/2010
certificado de pensiones horizonte por ruby ... [Actualidad] 32 14/02/2010
jalar datos a un listbox por happypeace31 ... [Visual Basic .NET] 1 21/09/2009
fecha valida datetimepicker por jess ... [Visual Basic .NET] 1 04/03/2010
Mi numero de autogenerado por chari ... [Visual Basic .NET] 4 01/03/2010
quiero saber en que entidad estoy afiliada a cesantias y pensiones por adriana ... [WIN 98/NT/2000/XP] 23 28/11/2009
Certificado de afiliacion Pensiones y Cesantias por VIVIANA ... [Actualidad] 1 10/03/2010
CERTIFICADO por LIZETH ... [Actualidad] 0 11/03/2010
certificado de afiliación de pensiones y cesantias por secre ... [Actualidad] 111 28/01/2010
Solicitud certificado de afiliaciones a pensiones y cesantias proteccion por hz ... [Actualidad] 54 10/02/2010
certificado pensiones horizonte por angela patricia rodriguez ... [Actualidad] 135 26/01/2010
pensiones por eduard ... [Visual Basic 6.0] 0 11/03/2010

Access CGI JSP ORACLE UNIX
Actualidad HTML/DHTML/XHTML LINUX PHP Visual Basic .NET
ASP ISAPI MS DOS Power Builder Visual Basic 6.0
ASP.NET Java mySQL SQL WIN 98/NT/2000/XP
C# JavaScript Opinion SQL Server

devjoker  Te recomendamos además ...
01/01/2005 Conceptos básicos.    forma parte de...Iniciación a las bases de datos
21/07/2006 Funciones integradas de PL/SQL    forma parte de...Tutorial PL/SQL
02/09/2007 Procedimientos almacenados en Transact SQL    forma parte de...Tutorial de Transact SQL
22/10/2005 Consultas combinadas. JOINS    forma parte de...Tutorial SQL
22/10/2005 Componentes del lenguaje SQL    forma parte de...Tutorial SQL
01/06/2006 Cursores de actualización en PL/SQL    forma parte de...Tutorial PL/SQL
03/10/2006 Programacion con C#    forma parte de...Tutorial C#
10/06/2007 Multiples escritorios en Windows XP
11/09/2006 Trabajar con datos de tipo BLOB en ORACLE
18/09/2008 Generar archivos PDF con C#

 

Encuesta
¿A que perfil te adaptas mejor?




[Ver] [Votar]