 |
|
 |
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;
|
| Añadir comentario ... |
Para preguntar utiliza los foros
|
|

|
Paquetes en PL/SQL |
|
Autor:
Pedro Herrarte Sánchez
|
|
Visitas:
35994 |
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:
45
|
Comentarios:
0
|
Archivo:
Articulos
|
|
Visitas:
109
|
Comentarios:
0
|
Archivo:
Articulos
|
Visitas:
156
|
Comentarios:
0
|
Archivo:
Articulos
|
Visitas:
34
|
Comentarios:
0
|
Archivo:
Articulos
|
Visitas:
285
|
Comentarios:
1
|
Archivo:
Articulos
|
Visitas:
842
|
Comentarios:
2
|
Archivo:
Articulos
|
Visitas:
712
|
Comentarios:
1
|
Archivo:
Articulos
|
Visitas:
451
|
Comentarios:
0
|
Archivo:
Articulos
|
Visitas:
1054
|
Comentarios:
1
|
Archivo:
Articulos
|
Visitas:
250
|
Comentarios:
0
|
Archivo:
Articulos
|
|
|
|
 |
| Encuesta |
|
¿A que perfil te adaptas mejor? |
|
|
|
|
|
|
|
|
 |