Los paquetes tienen dos partes: una especificación y un cuerpo que están almacenados por separado en la base de datos.



Documentos relacionados
Enlaces relacionados:

Sintaxis: CURSOR nombre_cursor[(param1 [IN] tipo1,... )] IS consulta ;

MATERIAL 2 EXCEL 2007

Curso de PHP con MySQL Gratis

HERRAMIENTAS DE ACCESS ACCESS Manual de Referencia para usuarios. Salomón Ccance CCANCE WEBSITE

MANUAL DEL PROGRAMA DE ASESORAMIENTO (Asesores) Navegador y limpiar caché/cookies...2 Acceso al programa de Asesoramiento... 7

Curso Internet Básico - Aularagon

Modulo 1 El lenguaje Java

Comerciales. Comisiones en Documentos de Venta WhitePaper Enero de 2008

MANUAL DE USUARIO DE LA HERAMIENTA CONFIGURACION DE PRESUPUESTOS PARA DISTRIBUIDORES

SEGUIMIENTO EDUCATIVO. Comunicaciones

Programa Presupuestos de Sevillana de Informática.

La ventana de Microsoft Excel

Estimado usuario. Tabla de Contenidos

Un ejemplo teórico de trigger podría ser éste:

5- Uso de sentencias avanzadas

GUÍA RÁPIDA DE TRABAJOS CON ARCHIVOS.

CÓMO CREAR NUESTRO CATÁLOGO

En cualquier caso, tampoco es demasiado importante el significado de la "B", si es que lo tiene, lo interesante realmente es el algoritmo.

5.8. REGISTRO DE FACTURAS.

Centro de Capacitación en Informática

Combinar comentarios y cambios de varios documentos en un documento

GUÍA TÉCNICA PARA LA DEFINICIÓN DE COMPROMISOS DE CALIDAD Y SUS INDICADORES

Oracle básico (IV): Programación en PL/SQL

Tema 6. Reutilización de código. Programación Programación - Tema 6: Reutilización de código

Ejercicios - Persistencia en Android: ficheros y SQLite

Programa diseñado y creado por Art-Tronic Promotora Audiovisual, S.L.

Teclado sobre una PDA para Personas con Parálisis Cerebral

EXTRACTO Descripción del uso y manejo de SIRAIS 1.2

Comercial Cartas de Fidelización

- Bases de Datos - - Diseño Físico - Luis D. García

MANUAL DE AYUDA HERRAMIENTA DE APROVISIONAMIENTO

CASO PRÁCTICO DISTRIBUCIÓN DE COSTES

Proyectos de Innovación Docente

**NOTA** las partes tachadas todavía no están escritas, se ira actualizando poco a poco el documento

Cómo gestionar menús en Drupal 7

A25. Informática aplicada a la gestión Curso 2005/2006 Excel Tema 7. Funciones avanzadas de Excel II

DESCARGA E INSTALACIÓN DE LA DOCUMENTACIÓN PARA LAS CLASES DEL API DE JAVA. CONSULTAR EN LOCAL O EN INTERNET? (CU00910C)

MANUAL TIENDA VIRTUAL. Paseo del Gran Capitán, Nº 62, Salamanca. Telf.: Fax:

ESPOCH ESCUELA DE MEDICINA HERNANDEZ MAYRA FORMULAS Y DUNCIONES BASICAS ESPOCH

Hoja1!C4. Hoja1!$C$4. Fila

Tutorial de Introducción a la Informática Tema 0 Windows. Windows. 1. Objetivos

InfoPath forma parte del paquete ofimático de Microsoft desde la versión XP (2003).

GENERAR DOCUMENTOS HTML USANDO LENGUAJE PHP. EJERCICIO RESUELTO EJEMPLO SENCILLO. (CU00733B)

Adaptación al NPGC. Introducción. NPGC.doc. Qué cambios hay en el NPGC? Telf.: Fax.:

INSTRUCTIVO DEL COMANDO MAKE

SMS PUSH SMS ENCUESTAS INTERNET FAX

EDWIN KÄMMERER ORCASITA INGENIERO ELECTRÓNICO


Manual de ayuda para crear y gestionar Tareas, como actividad evaluable

Reservas - Rooming List

Base de datos relacional

UTILIZACIÓN DE UNA CUENTA DE CORREO ELECTRÓNICO (NUEVO) Acceso al correo electrónico

INSTALACIÓN DE ORACLE 8i (8.1.7) SOBRE NT

1. INTRODUCCIÓN 3 2. INSTALACIÓN DE LA APLICACIÓN PACK PYME Proceso de Instalación y Arranque... 5

Backup & Recovery Oracle 9i. Las copias físicas offline, conocidas como Backups en frío, se realizan cuando la Base de Datos está parada.

NORMA (SEPA) 22/11/2013

TUTORIAL SOBRE EL MANEJO DE LA OFICINA VIRTUAL PARA LA REMISIÓN DE INFORMES DE DOCENCIA VIRTUAL VÍA ADMINISTRACIÓN ELECTRÓNICA

Práctica 10. Redes Neuronales

LABORATORIO Nº 2 GUÍA PARA REALIZAR FORMULAS EN EXCEL

MANUAL DE AYUDA MÓDULO GOTELGEST.NET PREVENTA/AUTOVENTA

Problemas y ventajas de medir con BIM

L204 DVD-ROM 1 Audio transcripts: Unidad 1

USO DEL COMANDO. Fdisk. Autor :. Alejandro Curquejo. Recopilación :. Agustí Guiu i Ribera. Versión :.. 1.0

RESOLUCIÓN DE ERRORES EN MOODLE CAMPUS VIRTUAL-BIRTUALA UPV-EHU

NOVEDADES Y MEJORAS. datahotel versión 9.00 TRABAJAR CON I.V.A INCLUIDO

Figura 4.1 Clasificación de los lenguajes de bases de datos

Manual de usuario de Solmicro BI. Página 1

GUIA APLICACIÓN DE SOLICITUDES POR INTERNET. Gestión de Cursos, Certificados de Aptitud Profesional y Tarjetas de Cualificación de Conductores ÍNDICE

Índice general de materias LECCIÓN 7 74

Informática I Notas del curso

NemoTPV SAT Manual de usuario 1. NemoTPV SAT APLICACIÓN DE GESTIÓN DE SERVICIO TÉCNICO PARA PUNTOS DE VENTA DE EUSKALTEL

MANUAL DE AYUDA TAREA PROGRAMADA COPIAS DE SEGURIDAD

QUÉ ES UNA BASE DE DATOS Y CUÁLES SON LOS PRINCIPALES TIPOS? EJEMPLOS: MYSQL, SQLSERVER, ORACLE, POSTGRESQL, INFORMIX (DV00204A)

Manual etime para supervisores

Trabajos de Ampliación. Bases de datos NoSQL.

Esta extensión está obsoleta a partir de PHP 5.5.0, y será eliminada en el futuro

PROPUESTAS COMERCIALES

En términos generales, un foro es un espacio de debate donde pueden expresarse ideas o comentarios sobre uno o varios temas.

Base de datos Procedimientos Almacenados y Funciones

Documentación de la Práctica 1 para la asignatura de Nuevas Tecnologías de la Programación (NTP)

Manual de OpenOffice Impress

VAST: Manual de usuario. Autores: Francisco J. Almeida-Martínez Jaime Urquiza-Fuentes

Que es Velneo vdataclient V7?

PL/SQL. Con PL/SQL vamos a poder programar las unidades de programa de la base de datos Oracle:

6.1. Conoce la papelera

Documentación del Terminal

ALMACEN 1. En el ejemplo se muestra al proveedor 1, que realiza la fase 40. Automáticamente se creó el almacén P1.

Alta. En la plataforma. Uned- lued - Formatic. Patricia Rodríguez Mara Aguiar

Capítulo 2 Análisis del Sistema de Administración de Información de Bajo Costo para un Negocio Franquiciable

Proceso de cifrado. La fortaleza de los algoritmos es que son públicos, es decir, se conocen todas las transformaciones que se aplican al documento

INVENTARIO INTRODUCCIÓN RESUMEN DE PASOS

PHP Perfect SQL v1.0 (SQL perfectas en PHP)

Oficina Online. Manual del administrador

Pascual Vicente, Informática. MANUAL PROCESO DE ADAPTACIÓN DE CONTABILIDAD AL PGC 2007

e-conocimiento Manual de uso

REGISTRO ELECTRÓNICO DE FACTURAS

El proceso de edición digital en Artelope y CTCE

Solución al Reto Hacking v2.0 de Informática 64

NOTAS TÉCNICAS SOBRE EL SIT: Definición y Configuración de Usuarios

Transcripción:

8. PAQUETES DE BASE DE DATOS Los paquetes nos van a permitir agrupar conceptos PL/SQL como pueden ser tipos, procedimientos y funciones. Por ejemplo: una paquete de Contabilidad podrá contener procedimientos de inserción de asientos, procedimientos de comprobación de diario contable, funciones de calculo de balances, etc, etc... Para los que ya habéis visto algún lenguaje de programación, lo podéis relacionar con las librerías, aunque no lo son exactamente (existen librerías también en PL/SQL usadas en Forms y Reports) ya que los paquetes se almacenan en la base de datos y por tanto todas sus funciones y procedimientos son ejecutados por el servidor Oracle. De ahí su utilidad en una aplicación cliente/servidor. Los paquetes tienen dos partes: una especificación y un cuerpo que están almacenados por separado en la base de datos. Especificación: Es el interface donde se declaran los tipos, variables, excepciones, constantes, cursores, procedimientos y funciones que vamos a implementar en el paquete. Cuerpo: Aquí es donde definimos completamente lo que hemos declarado en la especificación del paquete. Es decir: implementamos las especificaciones. Un paquete, una vez compilado puede ser compartido por varios usuarios y/o aplicaciones (no voy a entrar en el tema usuarios/sesiones ya que sería parte de un curso de la base de datos. Por el momento vamos a suponer que solo tenemos un usuario de base de datos que es con el que realizamos los ejemplos.) siempre y cuando así se especifique en la base de datos. Cuando se llama la primera vez al procedimiento ó función de un paquete PL/SQL, éste se carga en la memoria del servidor, por lo que las llamadas posteriores se efectúan más rápidamente al no tener que acudir al disco. 8.1 VENTAJAS DE LOS PAQUETES Podemos usar paquetes o usar procedimientos y funciones almacenados en la base de datos. Cual es la diferencia?. Qué ventajas obtenemos al usar paquetes?. Bien, pues son estas (que no son pocas): Modularidad: Estamos agrupando en un módulo (paquete) con un nombre las estructuras relacionadas con un objetivo, temática, etc.. de nuestra aplicación. Facilidad de diseño de aplicación: En principio todo lo que necesitamos en la especificación del paquete es la información del interface. Podemos escribir y compilar la especificación sin su cuerpo. Después también podremos compilar los subprogramas almacenados que referencian al paquete. Es decir: si estoy escribiendo una función almacenada o en otro paquete y necesito crear una función en otro paquete porque la voy a usar en esta que estoy escribiendo, tan solo tendré que definirla en la especificación del paquete donde vaya a residir. Ya la escribiré más tarde, cuando termine con la que estoy escribiendo ahora. Al compilar su especificación, ya podemos seguir escribiendo nuestra función haciendo uso de la llamada y compilándola. Como creo que igual no me he explicado bien, allá va un ejemplo: Pág 1 de 7

Me encuentro escribiendo la función Calcula_Comisiones que me calcula comisiones de las facturas de la empresa entre dos fechas que le paso como parámetros. Pero resulta que me doy cuenta que podría utilizar una función que calculara la comisión de una factura y con su resultado ir sumando hasta conseguir las comisiones que quiero. Bien, pues me voy a la cabecera (especificación) del paquete COMISIONES y creo la declaración de la función Comision_Factura que me calculará la comisión de una factura que le pasaré como parámetro. Una vez compilada la especificación del paquete puedo seguir escribiendo el código de la función Calcula_Comisiones incluyendo la llamada a Comision_Factura. Cuando termine de escribirla la puedo compilar (a pesar de que Comision_Factura solo está especificada pero NO escrita). Por supuesto, para que funcione Calcula_Comisiones tendré que escribir el código de Comision_Factura. Información restringida: Podemos decidir qué subprogramas son públicos (visibles y accesibles) o privados (ocultos e inaccesibles). El paquete oculta la definición de los subprogramas privados a los usuarios que no tengan derechos. Sin embargo esto no afecta a la aplicación que haga uso de ellos. Por supuesto también estamos ocultando los detalles de la implementación, con la ventaja que eso supone en algunos casos. (Algoritmos de cifrado, cálculo de claves, etc...) Más funcionalidad: durante la sesión tenemos disponibles las variables y cursores públicos definidos en los paquetes. De esta forma, pueden ser compartidos por todos los subprogramas que se ejecuten, ya sean de otros paquetes, almacenados en la base de datos o de aplicación. También podremos mantener datos en transacciones sin tener que almacenarlos en la base de datos. Mejor rendimiento: Ya hemos dicho que cuando llamamos a un subprograma de un paquete, éste se carga en memoria. Se carga todo el paquete, por lo que las siguientes llamadas a cualquier subprograma del paquete son hechas a la memoria con el consiguiente aumento de rendimiento. Sobrecarga: Los paquetes nos permiten sobrecargar funciones y/o procedimientos. Es decir: podemos crear varios subprogramas con el mismo nombre en el mismo paquete, pero cada uno con distinto tipo y número de parámetros. Al realizar la llamada se decide, según los parámetros utilizados en ella, el subprograma a ejecutar. 8.2 CREACION DE UN PAQUETE Crearemos un paquete en dos fases: primero la especificación y luego la implementación o cuerpo. Los paquetes de programas públicos son aquellos que se declaran en la especificación y que se definen en el cuerpo. Los paquetes de programas privados son los que se declaran y definen solo en el cuerpo (suelen ser subprogramas dentro de otros subprogramas, por lo que su ámbito es privado y su visibilidad es local). Como ya dijimos al principio del curso, suponemos que no disponemos de más herramientas que un editor de textos y el SQL*Plus (consola de SQL), por lo que vamos a crear un paquete mediante su instrucción pura y dura. Seguiremos tres pasos básicos: Escribir la sentencia CREATE PACKAGE Pág 2 de 7

para crear la especificación del paquete, escribir la sentencia CREATE PACKAGE BODY para crear el cuerpo del paquete y finalmente llamar a un procedimiento público del paquete. También es conveniente recordar que la especificación del paquete puede existir sin la implementación o cuerpo, pero no al revés, y que es conveniente borrar un subprograma almacenado si lo hemos incorporado a un paquete, para evitar código inútil y facilitar la administración y mantenimiento. Ya veremos que podrían coexistir ya que la llamada al subprograma que reside dentro del paquete es especial por lo que no hay duda a cual estamos llamando. 8.2.1 Creamos la especificación del paquete Sintaxis: CREATE [OR REPLACE] PACKAGE nombre_paquete IS AS definiciones públicas de tipos, variables y cursores especificaciones de subprogramas END nombre_paquete ; La opción OR REPLACE la utilizamos cuando la especificación del paquete ya existe. Importante: Si añadimos un subprograma, hay que volver a escribir la sentencia completa CREATE OR REPLACE PACKAGE con todos los datos que ya tenia más la nueva especificación, por eso se suelen guardar en ficheros de texto estas sentencias (el que se use herramientas más cómodas obviará este comentario ya que mediante ellas, se pueden añadir, modificar y eliminar contenidos de los paquetes simplemente editando el texto de los mismos). La dualidad IS AS es debida a que si utilizamos una herramienta que viene con el entorno de desarrollo de Oracle llamada Procedure Builder tenemos que usar IS. En caso contrario da lo mismo lo que usemos (cuestión de versiones). Si declaramos alguna variable dentro de la especificación de un paquete y no la inicializamos, ésta se inicializa como NULL. Como siempre, un ejemplo nos aclarará las cosas: CREATE OR REPLACE Package CURSO_PL_SQL IS TYPE tipo_reg_empleado IS RECORD (fila_emp empleados%rowtype) ; vp_empresa NUMBER := 1; / PROCEDURE inserta_departamento(p_codigo IN departamentos.codigo%type, p_nombre IN departamentos.nombre%type, p_resultado OUT varchar2); FUNCTION nombre_departamento(p_codigo IN departamentos.codigo%type) return varchar2 ; Este texto lo introduciremos en SQL*Plus o en un archivo de texto para ejecutarlo en SQL*Plus y nos creará la especificación del paquete CURSO_PL_SQL. Como se ve, la primera linea (azul) define un tipo de datos registro que será público, es decir, todos los subprogramas lo podrán Pág 3 de 7

usar. La segunda linea (verde) define e inicializa una variable también pública, y las restantes lineas (rojo) definen el interface de un procedimiento y de una función con sus parámetros correspondientes. La implementación en código de dichos subprogramas no está en el cuerpo del paquete. 8.2.2 Creamos el cuerpo del paquete Sintaxis: CREATE [OR REPLACE] PACKAGE BODY nombre_paquete IS AS definiciones privadas de tipos, variables y cursores implementación de subprogramas END nombre_paquete ; Lo dicho para la especificación del paquete vale también para el cuerpo del mismo, aunque hay algo más. Si definimos un subprograma que referencia a otro del mismo paquete, ese otro debe estar definido antes (a más de uno le sonará esto de otros lenguajes), aunque hay una variante que no veremos para evitar esto. Vamos a crear el cuerpo del paquete que antes hemos especificado. CREATE OR REPLACE Package Body CURSO_PL_SQL IS type tipo_reg_dep IS RECORD (fila_dep departamentos%rowtype) ; PROCEDURE inserta_departamento(p_codigo IN departamentos.codigo%type, p_nombre IN departamentos.nombre%type, p_resultado OUT varchar2) IS BEGIN INSERT INTO DEPARTAMENTOS VALUES(p_codigo, p_nombre) ; p_resultado:= 'INSERCION CORRECTA'; EXCEPTION WHEN OTHERS THEN p_resultado := 'ERROR AL INSERTAR EL REGISTRO' ; FUNCTION nombre_departamento(p_codigo IN departamentos.codigo%type) return varchar2 IS v_nombre departamentos.nombre%type; BEGIN SELECT nombre INTO v_nombre FROM departamentos WHERE codigo=p_codigo ; EXCEPTION WHEN NO_DATA_FOUND THEN v_nombre := '** No encontrado departamento ' to_char(p_codigo) ; WHEN TOO_MANY_ROWS THEN v_nombre := '** Más de un registro con código ' to_char(p_codigo) '. Avise al Admin.' ; WHEN OTHERS THEN v_nombre := '** ERROR INESPERADO **' ; -- FIN DEL CUERPO DEL PAQUETE / Pág 4 de 7

Bien, ya tenemos más materia eh? ;-) Revisemos lo que tenemos: Tras la sentencia CREATE OR REPLACE PACKAGE BODY (diferencia con la sentencia de la especificación), tenemos definido un tipo de datos RECORD (azul) que será privado para el paquete, y después la implementación (en rojo) del procedimiento y la función especificadas anteriormente. En este caso el procedimiento serviría para insertar un registro de departamentos, controlando un posible error inesperado, y devolviendo un status de resultado en una variable de salida (p_resultado). La función nos devuleve el nombre de un departamento dado (pasado como parámetro) y controla los posibles errores que puedan producirse. La excepción TOO_MANY_ROWS (demasiados registros) no puede darse si tenemos definido el campo codigo como PRIMARY KEY de la tabla, ya que NUNCA podrían haber dos departamentos con el mismo código. Aún así, la he puesto para documentar otro tipo de excepción. Algo muy importante a tener en cuenta es que si se produce una excepción, estamos capturándolas y ocultando el error al sistema. Vamos, que para nuestra aplicación no ha pasado nada, simplemente nos devuelve diferentes valores según el error producido. Esto que parece muy bonito, no lo es tanto cuando queremos tener un control de transacciones y obligar a un ROLLBACK si algo ha fallado. Para obligar, a pesar de haber capturado una excepción, a notificar el error, usaremos el built-in RAISE_APPLICATION_ERROR() que nos proporciona Oracle. Con este built-in (que es un procedimiento interno al fin y al cabo) lo que hacemos es relanzar la excepción que se había producido antes de que la capturásemos. Para el caso anterior (el del procedimiento, por ejemplo) sería: PROCEDURE inserta_departamento(p_codigo IN departamentos.codigo%type, p_nombre IN departamentos.nombre%type, p_resultado OUT varchar2) IS BEGIN INSERT INTO DEPARTAMENTOS VALUES(p_codigo, p_nombre) ; p_resultado:= 'INSERCION CORRECTA'; EXCEPTION WHEN OTHERS THEN p_resultado := 'ERROR AL INSERTAR EL REGISTRO' ; RAISE_APPLICATION_ERROR(-20001, p_resultado); Con esto logramos que, tras capturarse el error, guardemos en p_resultado la cadena que queremos devolver y además relanzar la excepción para que nuestra aplicación sepa que ocurrió un error. El número (-20001) es un argumento que se le pasa para indicar el número de error ocurrido. En nuestro caso es un error personalizado, por lo que la numeración debe estar entre -20000 y -20999 (cosas de Oracle). Ahora bien, si queremos saber el error exacto y su número, disponemos de dos variables de sistema ligadas a las excepciones que son SQLCODE (numérico) que contendrá el numero de error (típico ORA-nnnnnn) y SQLERRM (varchar2) que contendrá el texto original del error. Vamos que podríamos haber hecho esto para tener más información: RAISE_APPLICATION_ERROR(-20001, TO_CHAR(SQLCODE) '-' SQLERRM ' ' p_resultado); Pág 5 de 7

8.2.3 Ejecutamos algo del paquete Después de haber creado un paquete y haber sido almacenado en la base de datos (todo se hace a la vez) podemos invocar a un subprograma dentro del paquete o desde fuera del mismo, dependiendo si el subprograma es público o privado. Cuando llamamos a un subprograma desde dentro de otro subprograma del paquete, basta con hacer una llamada normal del tipo: v_departamento := nombre_departamento( v_codigo ); Si llamamos a un subprograma desde fuera (debe ser público) lo haremos así desde SQL*Plus: SQL> EXECUTE nombre_paquete.nombre_procedimiento(parametros) Si queremos modificar una variable pública (más bien global) como la del paquete de ejemplo, haríamos: SQL> EXECUTE CURSO_PL_SQL.vp_empresa := 2 Otra opción para usar las funciones (sólo funciones) de un paquete es hacer que forme parte de una sentencia SELECT. Como ya sabemos, las columnas de una SELECT pueden ser expresiones, y que es una función?. SQL> SELECT codigo, nombre, departamento, CURSO_PL_SQL.nombre_departamento(codigo) FROM EMPLEADOS ; Obteniendo así lo que podíamos haber obtenido con una SELECT enlazada con la tabla de DEPARTAMENTOS ;-) Os dejo que penséis qué será lo más óptimo: Esto ó una join? Resumiendo: Crear paquetes flexibles: Es decir, que sean lo más generales posibles y se puedan reutilizar en futuras aplicaciones. Es conveniente evitar crear funciones que ya las implemente Oracle (es absurdo repetir). Definir la especificación del paquete antes que el cuerpo: Las especificaciones reflejan el diseño de la aplicación, por lo que hay que definirlas antes que el cuerpo. La especificación del paquete solo debe contener construcciones públicas: Sólo los subprogramas que deben ser visibles para los usuarios del paquete. De esta forma, otro usuario no podrá hacer un mal uso de nuestro paquete. La especificación del paquete debería contener el mínimo numero de construcciones: Esto es para reducir la necesidad de compilar cuando se cambia el código. Los cambios en el cuerpo del paquete no requieren recompilación de programas/paquetes dependientes, pero los cambios en la especificación sí lo requieren. Cada subprograma almacenado de forma independiente o en algún paquete que referencie al nuestro deberá ser recompilado (tranquilos que Oracle se encarga de avisar con unos bonitos mensajes de error: ORA-04068: se ha anulado el estado existente de los paquetes y ORA-04061: El estado existente del paquete CURSO_PL_SQL ha sido invalidado). Pág 6 de 7

8.3 BORRADO DE UN PAQUETE Sí, otra vez DROP, jejeje, en este caso: SQL> DROP PACKAGE nombre_del_paquete y para el cuerpo: SQL> DROP PACKAGE BODY nombre_del_paquete Pág 7 de 7