 |
|
 |
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.
|
| |
 |
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
|
|

|
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
|
Visitas:
794
|
Comentarios:
2
|
Archivo:
Articulos
|
Visitas:
749
|
Comentarios:
3
|
Archivo:
Articulos
|
Visitas:
654
|
Comentarios:
2
|
Archivo:
Articulos
|
Visitas:
3145
|
Comentarios:
2
|
Archivo:
Articulos
|
Visitas:
14504
|
Comentarios:
7
|
Archivo:
Articulos
|
Visitas:
1478
|
Comentarios:
3
|
Archivo:
Articulos
|
|
Visitas:
691
|
Comentarios:
2
|
Archivo:
Articulos
|
|
Visitas:
369
|
Comentarios:
0
|
Archivo:
Articulos
|
Visitas:
2013
|
Comentarios:
2
|
Archivo:
Articulos
|
|
|
 |
|
 |