0% encontró este documento útil (0 votos)
548 vistas23 páginas

Referencia PLSQL

El documento proporciona una introducción al lenguaje de programación PL/SQL. PL/SQL es un lenguaje estructurado basado en bloques que permite realizar operaciones SQL y extender la funcionalidad de la base de datos mediante el uso de variables, bucles y condicionales. El documento describe los diferentes tipos de bloques PL/SQL, la sintaxis básica, declaración de variables y constantes, y las estructuras de control disponibles en PL/SQL.
Derechos de autor
© Attribution Non-Commercial (BY-NC)
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
548 vistas23 páginas

Referencia PLSQL

El documento proporciona una introducción al lenguaje de programación PL/SQL. PL/SQL es un lenguaje estructurado basado en bloques que permite realizar operaciones SQL y extender la funcionalidad de la base de datos mediante el uso de variables, bucles y condicionales. El documento describe los diferentes tipos de bloques PL/SQL, la sintaxis básica, declaración de variables y constantes, y las estructuras de control disponibles en PL/SQL.
Derechos de autor
© Attribution Non-Commercial (BY-NC)
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 23

Referencia PL/SQL

1. Introduccin al Procedural Language / SQL (PL/SQL)


El lenguaje PL/SQL es una extensin procedural del lenguaje SQL creada por Oracle para trabajar con la base de datos. La sintaxis del lenguaje est basada en ADA. Soporta todas las instrucciones DML de SQL (e.g. SELECT, INSERT, UPDATE y DELETE), instrucciones para el control de transacciones, control de cursores y aade estructuras de control condicional y bucles. Para utilizar el resto de instrucciones SQL (e.g. CREATE TABLE, etc.) es necesario utilizar SQL dinmico y paquetes de funciones proporcionados en el servidor como DBMS_SQL. El concepto bsico de PL/SQL y unidad mnima de programacin es el bloque. De este modo, PL/SQL es un lenguaje estructurado en bloques. Los tipos de bloque soportados por PL/SQL son: Bloque annimos. Subprogramas (bloques nombrados): procedimientos, funciones y paquetes. Disparadores. Algunas caractersticas generales de PL/SQL: El lenguaje PL/SQL no es sensible a maysculas y minsculas. Es necesario declarar los identificadores (e.g. variables, procedimientos, etc.) antes de que sean utilizados. Ejemplo de bloque PL/SQL:
DECLARE Xnombre clientes.nombre%TYPE; Xarticulo ventas.art%TYPE; BEGIN SELECT nombre, art INTO xnombre, xarticulo FROM clientes, ventas WHERE clientes.codigo = ventas.codigo AND ventas.fecha = sysdate-7; DBMS_OUTPUT.PUT_LINE ( 'Solo una venta de '|| xarticulo ||' a: '||xnombre); EXCEPTION WHEN NO_DATA_FOUND THEN -- El SELECT no devolvi valores DBMS_OUTPUT.PUT_LINE ('No hay ventas hace una semana'); WHEN TOO_MANY_ROWS THEN -- SELECT devolvi ms de un valor DBMS_OUTPUT.PUT_LINE ('Ms de una venta hace una semana'); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE ('Error inesperado'); END; /

1.1. Compilacin
Todos los bloques PL/SQL deben incluir al final una fila con el carcter '/' para compilar y ejecutar. Si no se introduce el carcter '/' el editor SQL*Plus no identifica que se haya finalizado el bloque PL/SQL y por tanto no lo compila ni ejecuta. Si no hay errores de compilacin o ejecucin se mostrar en la consola de SQL*Plus alguno de los siguientes mensajes:
PL/SQL procedure successfully completed. Procedimiento PL/SQL terminado correctamente.

En el caso de que el proceso de compilacin falle SQL*Plus muestra los errores de compilacin, incluyendo informacin acerca del problema y la posicin del mismo. En el caso particular de subprogramas almacenados (e.g. CREATE ) los errores no se muestran directamente. Para examinar los errores de compilacin y ejecucin de un programa almacenado se utiliza la se utiliza la orden:
SHOW ERRORS;

1.2. Salida por consola e interaccin con el usuario


Es posible mostrar datos por la consola de SQL*Plus desde un programa PL/SQL utilizando los procedimientos y funciones que se incluyen en el paquete DBMS_OUTPUT (ver seccin 4.5.2). Para poder utilizar la consola es necesario activar el eco del buffer ejecutando la siguiente orden:
SET SERVEROUTPUT ON [FORMAT WRAPPED] [SIZE<tamao>]

Aunque es posible trabajar con SQL*Plus, iSQL*Plus y SQL*Worksheet indistintamente para crear bloques PL/SQL, para interactuar con el usuario es recomendable utilizar SQL*Plus. A travs de SQL*Plus se ofrecen distintos mecanismos para poder interactuar con el usuario, habitualmente para pedirle informacin por teclado. Las instrucciones ms relevantes para interactuar con el usuario son: ACCEPT. Permite leer un dato desde la entrada y almacenarlo en una variable. PAUSE. Muestra un texto y espera a que el usuario pulse INTRO. Existen otros mecanismos adicionales para interactuar con el usuario como la sustitucin de variables (ver Writing Interactive Commands en [7]) y las variables vinculadas (ver Using Bind Variables en [7]).

1.3. Referencias del apartado


Ver PL/SQL Overview (captulo 1 y captulo 14) en [1]. Ver Overview of PL/SQL en [2]. Ver SHOW ERROS en [4]. Ver SET SERVEROUTPUT en [4]. Ver SQL*Plus Basics en [4]. Ver Using Scripts in SQL*Plus en [4]. Ver ACCEPT, PROMPT y PAUSE en [4].

2.

Bloques annimos

Los bloques PL/SQL presentan una estructura especfica compuesta de tres partes bien diferenciadas: DECLAREBEGIN. En esta seccin se declaran todas las constantes y variables que se van a utilizar en el bloque PL/SQL. Esta seccin es opcional. BEGINEXCEPTION/END. Esta seccin incluyen todas las instrucciones a ejecutar. Esta seccin es obligatoria. EXCEPTIONEND. La seccin de excepciones en donde se definen los manejadores de errores que soportar el bloque PL/SQL. Esta seccin es opcional. De las anteriores, nicamente la seccin de ejecucin es obligatoria, que quedara delimitada entre las clusulas BEGIN y END. El esquema general de un bloque PL/SQL queda del siguiente modo:

[<<nombre del bloque>>] [DECLARE] Declaracin de: Variables. Constantes. Cursores. Variables de excepcin para control de errores. Procedimientos / Funciones. ... BEGIN Instrucciones PL/SQL Bloques PL/SQL anidados NULL; -- sentencia que no hace nada [EXCEPTION] Control y tratamiento de errores. Punto al que se transfiere el control siempre que exista un problema. END [nombre del bloque]; /

El anidamiento de bloques PL/SQL es una prctica habitual para llevar a cabo la gestin de errores (gestin de excepciones) dentro del cdigo PL/SQL. Un ejemplo simple de bloque annimo PL/SQL es el siguiente:
DECLARE nombre_variable VARCHAR2(5); nombre_excepcion EXCEPTION; BEGIN SELECT 1 INTO nombre_variable FROM DUAL; EXCEPTION WHEN nombre_excepcion THEN NULL; -- Esta instruccin no hace nada END; /

2.1. Identificadores
Los identificadores, como en todo lenguaje de programacin, se utilizan para nombrar a los objetos que se emplean en un programa: variables, constantes, nombres de procedimientos y funciones, etc. Las restricciones para los identificadores son: Deben empezar por letra. El resto del identificador puede contener caracteres alfanumricos y caracteres especiales como '$', '#' o '_'. Pueden tener una longitud mxima 30 caracteres. Al igual que otros lenguajes procedimentales, los identificadores de los objetos tienen un alcance y una visibilidad (ver Scope and Visibility of PL/SQL Identifiers en [4]).

2.2. Comentarios
En un bloque PL/SQL se admiten dos tipos de comentarios: Comentarios de una lnea. Deben comenzar por '--'. Es posible aadir un comentario de lnea al final de una instruccin. Comentarios de ms de una lnea. El comentario debe incluirse dentro de '/* */'.

2.3. Declaraciones de variables y constantes


La sintaxis para declara una variable es la siguiente:

<nombre de variable> <tipo> [NOT NULL] [:= valor inicial] ;

Es necesario tener en cuenta que: Las variables se inicializan por defecto al valor NULL. Cualquier variable declarada como NOT NULL tiene que ser inicializada con un valor. La inicializacin puede incluir cualquier expresin legal de PL/SQL que devuelva un valor del tipo de la variable que se est declarando. No se pueden declarar varias variables en la misma sentencia. La sintaxis para declarar una constante es similar al a declaracin de una variable. En este caso es necesario definir el valor de la constante:
<nombre de constante> CONSTANT <tipo> := <valor> ;

2.3.1. Tipos de Datos Al declarar el tipo de una variable o constante se puede utilizar los siguientes tipos de datos (ver PL/SQL Datatypes en [4]): Tipos de datos SQL: INT, CHAR, VARCHAR, etc. Tipos de datos nativos Oracle: NCHAR, etc. BOOLEAN. Puede tomar los valores TRUE, FALSE, NULL. Compuestos: arrays, cursores, fila de tabla, construidos (colecciones y registros). Subtipos: VARCHAR(3), NUMBER(6,2), etc. <id>%TYPE y <id>%ROWTYPE. Los pseudo-tipos %TYPE y %ROWTYPE permiten definir el tipo de una variable o constante dependiendo del tipo de otro elemento. <id>%TYPE permite definir el tipo de una variable a partir del tipo de otra variable o de una columna de una tabla de la BBDD cuyo identificador es <id>. <id>%ROWTYPE permite definir el tipo de una variable de tipo registro donde los tipos de los componentes del registro se toman de las columnas de una tabla de la BBDD.
v1 INT; v2 v1%TYPE; -- Se toma el tipo de la variable v1 vNombre EMPLEADOS.nombre%TYPE; -- Se toma el tipo de la columna nombre de la tabla EMPLEADOS

2.4. Expresiones
Las expresiones PL/SQL constan de operandos y operadores. Los operandos de una expresin PL/SQL pueden ser valores literales (e.g. 2, 'Hola', DATE '2009-0423', etc.), variables, constantes y llamadas a funciones. Los operadores que se pueden incluir en las expresiones PL/SQL son similares a los operadores que se podan incluir en las expresiones SQL: Operadores aritmticos: +, -, *, /. Operadores lgicos: AND, OR y NOT. Operador de concatenacin de cadenas: '||'. Operadores de comparacin: =, <>, !=, <, >, <=, >=, IS NULL, BETWEEN, LIKE, IN. Las funciones que se pueden incluir en las expresiones PL/SQL tambin son similares a las funciones que se podan incluir en SQL a excepcin de las funciones de agregacin (e.g. COUNT, SUM, etc.) solo pueden ser utilizadas dentro de una sentencia SELECT.

2.5. Instrucciones
2.5.1. Asignacin Existen dos mecanismos de asignacin: utilizando el operador de asignacin (:=) y utilizando la instruccin SELECT INTO. Ejemplo:
res := suma_tot / elems; -- Ejemplo de asignacin total_A INT; -- Declaracin de variable previa ... SELECT COUNT(*) INTO total_A FROM TABLA1 WHERE NOM LIKE 'A';

2.5.2. Condicional PL/SQL dispone de algunas estructuras de control que permiten controlar el flujo del programa.
IF condicin THEN sentencia1; ... ; sentenciaN; [ELSIF condicin2 THEN sentencia1; ....; sentenciaN;] [ELSE sentencia1; ... ; sentenciaN;] END IF;

2.5.3. Bucles El bucle LOOP ejecuta las instrucciones que contiene hasta que ejecuta: una instruccin EXIT o EXIT WHEN condicin (y se cumple la condicin).
LOOP sentencia1; ... ; sentenciaN; [ IF condicion THEN EXIT; END IF; [ EXIT WHEN condicion ] END LOOP;

Bucles FOR:
FOR <contador> IN [REVERSE] <inicio>..<fin> LOOP sentencia1; ... ; sentenciaN; END LOOP;

Bucles WHILE:
WHILE <condicion> LOOP sentencia1; ... ; sentenciaN; END LOOP;

2.6. Control de errores: Excepciones


En PL/SQL la deteccin y gestin de condiciones de error se gestiona mediante el mecanismo de excepciones. Oracle incluye un conjunto de excepciones que identifican los errores en tiempo de ejecucin de las instrucciones PL/SQL, pero tambin es posible definir excepciones propias. Cuando ocurre un error durante la ejecucin de una instruccin PL/SQL Oracle marca esta condicin de error con una excepcin, deteniendo la ejecucin normal del bloque PL/SQL y transfiriendo el control a la seccin EXCEPTIONEND del bloque PL/SQL donde se incluirn los diferentes manejadores de excepciones. Si esta seccin

gestiona adecuadamente la excepcin, la ejecucin del bloque termina, en otro caso la excepcin se propaga transfiriendo el control al bloque PL/SQL que incluya al bloque que lanz la excepcin. Esta propagacin de la excepcin termina cuando algn bloque gestiona adecuadamente la excepcin o en su defecto gestionada por el servidor (enviando a la consola los mensajes de error correspondientes). Las excepciones predefinidas son lanzadas/levantadas automticamente por el sistema, no obstante, es posible lanzar las excepciones definidas por el usuario con la instruccin RAISE <id>, donde <id> es el identificador de la excepcin de usuario a lanzar. Por ejemplo la instruccin SELECT...INTO lanza varias excepciones para marcar condiciones de error: Lanza TOO_MANY_ROWS si la instruccin devuelve ms de una fila resultante. Lanza NO_DATA_FOUND si la instruccin no devuelve ninguna fila. 2.6.1. Gestin de Excepciones Cuando se lanza una excepcin el flujo de ejecucin normal se transfiere a la seccin EXCEPTIONEND del bloque PL/SQL donde se ha lanzado la excepcin. Esta seccin contiene los manejadores de excepciones, donde su estructura es:
EXCEPTION WHEN Nombre_excepcin1 THEN -- Manejador instruccin1; ...; instruccinN; WHEN Nombre_excepcin2 OR Nombre_excepcin3 THEN -- Otro manejador instruccin1; ...; instruccinN; ... WHEN OTHERS THEN -- Manejador por defecto (es opcional). Si no existe un manejador ms especfico se ejecutan las instrucciones de este manejador. instruccin1; ...; instruccinN; END;

Una vez que las instrucciones del manejador son ejecutadas, la ejecucin del bloque finaliza. Como posible instruccin dentro del manejador de excepciones se puede utilizar la instruccin RAISE (sin parmetro) para relanzar la excepcin que se est actualmente gestionando. El manejador OTHERS es el manejador por defecto, de modo que si no existe ningn manejador ms especfico para una excepcin, sta ser tratada en este manejador. Finalmente es posible gestionar varias excepciones a la vez en el mismo manejador de excepciones utilizando el operador OR entre los nombres de las excepciones. Ntese que las excepciones no solo se pueden lanzar en el cuerpo de bloque PL/SQL sino que pueden ser lanzadas como resultado de una mala inicializacin en una declaracin o como resultado de la ejecucin de alguna instruccin dentro de un manejador de excepciones. En ambos casos la excepcin se propaga al bloque PL/SQL que contenga al bloque que ha lanzado la excepcin. Debido al comportamiento para la gestin de excepciones, cuando se terminan de ejecutar las instrucciones del manejador de excepciones correspondiente la ejecucin del bloque termina. Si deseamos continuar con la ejecucin del bloque podemos utilizar la capacidad de PL/SQL de permitir el anidamiento de bloques, de modo que simularemos los bloques try-catch que podemos encontrar en otros lenguajes de programacin. Ejemplo:
DECLARE resultado INTEGER := 1;

BEGIN BEGIN SELECT 1 / 0 INTO resultado FROM DUAL; EXCEPTION WHEN ZERO_DIVIDE THEN resultado := -1; END; IF resultado > 0 THEN ELSE DBMS_OUTPUT.PUT_LINE('Error'); END IF; END; /

Algunas excepciones predefinidas de Oracle son: NO_DATA_FOUND, TOO_MANY_ROWS. Son lanzadas por problemas relacionados con los cursores implcitos (Seccin 3.1). INVALID_NUMBER, VALUE_ERROR, ZERO_DIVIDE. Son lanzadas por problemas relacionados con la evaluacin de operaciones numricas. CURSOR_ALREADY_OPEN, INVALID_CURSOR. Son lanzadas por problemas relativos a la gestin de cursores explcitos. 2.6.2. Excepciones de usuario Es posible utilizar excepciones de usuario dentro de un bloque PL/SQL. Para utilizar una excepcin de usuario es necesario: definir la excepcin y lanzarla. La definicin de una excepcin se realiza dentro de la seccin DECLARE del bloque PL/SQL y para lanzar la excepcin se utiliza la instruccin RAISE.
DECLARE excepcion_propia EXCEPTION; BEGIN RAISE excepcion_propia; EXCEPTION WHEN excepcion_propia THEN DBMS_OUTPUT.PUT_LINE('Excepcion capturada'); END; /

Las excepciones siguen las mismas reglas de visibilidad que el resto de identificadores de objetos de PL/SQL, es decir, son visibles en el propio bloque y en los bloques anidados. Cuando se lanza una excepcin desde un bloque PL/SQL y sta no es gestionada, la excepcin se propaga al bloque superior o en su defecto al sistema (que mostrar un mensaje de error genrico). Ntese que, ya que la excepcin definida por el usuario slo tiene mbito local al bloque donde se lanza, el nico manejador que se puede utilizar es el manejador OTHERS. Por ejemplo dado el siguiente subprograma almacenado:

CREATE PROCEDURE problemas1 ( ) AS x EXCEPTION; BEGIN RAISE x; END problemas1;

Cualquier bloque PL/SQL que llame a este procedimiento almacenado y quiera gestionar la excepcin de aplicacin debe hacerlo a travs del manejador OTHERS.
BEGIN problemas1(); EXCEPTION WHEN OTHERS THEN instruccin1; ...; instruccinN; END;

Existe otro mecanismo para definir excepciones usuario utilizando el procedimiento RAISE_APPLICATION_ERROR. La ventaja de utilizar este procedimiento es que la aplicacin puede asignar un cdigo de error ORA-XXXXX y un mensaje descriptivo. El procedimiento RAISE_APPLICATION_ERROR(num_error, mensaje) tiene los siguientes parmetros: num_error. Cdigo de error que el desarrollador asigna a la excepcin de usuario. Este cdigo debe estar dentro del rango -20000 .. -20999. mensaje. Mensaje de texto asignado a la excepcin. El tamao mximo del mensaje es de 2048 bytes. El uso de RAISE_APPLICATION_ERROR es particularmente til en los subprogramas almacenados, ya que permite definir un conjunto de errores de aplicacin descriptivos. Por ejemplo, se puede definir una excepcin para especificar que se ha violado una dependencia funcional particular:
CREATE PROCEDURE compruebaDFs ( ) AS BEGIN RAISE_APPLICATION_ERROR(-20101, 'La DF1 A->B se ha violado'); END problemas2;

Tambin es posible gestionar las excepciones de aplicacin lanzadas con RAISE_APPLICATION_ERROR utilizando el manejador OTHERS, sin embargo, tambin es posible asociar el cdigo de error particular que ha definido el desarrollador con una declaracin de excepcin utilizando la directiva PRAGMA INIT_EXCEPTION. A continuacin se muestra un bloque PL/SQL que captura la excepcin del anterior procedimiento almacenado:
DECLARE df1_violada EXCEPTION; /* Mapea el cdigo de error que devuelve RAISE_APPLICAITON_ERROR a una excepcin definida por el usuario */ PRAGMA EXCEPTION_INIT(df1_violada, -20101); BEGIN compruebaDFs(); EXCEPTION WHEN df1_violada THEN instruccin1; ...; instruccinN; END;

2.7. Referencias del Apartado


Ver PL/SQL Datatypes en [4]. Ver Selecting Datatypes en [2].

Ver Native Datatypes en [1]. Ver Handling PL/SQL Errors en [4].

3.

Cursores

Los cursores representan una referencia a una zona de la memoria de trabajo de Oracle utilizada para almacenar toda la informacin necesaria para ejecutar una instruccin SQL (ver Cursors en [1]). Existen dos tipos de cursores: implcitos y explcitos. Los cursores implcitos son cursores que utiliza implcitamente Oracle para ejecutar las instrucciones de manipulacin de datos incluidas las consultas que devuelven una nica fila. Los cursores explcitos son necesarios para consultas en las que se devuelva ms de una fila.

3.1. Cursores implcitos


El caso ms habitual de cursor implcito es el que cursor que se crea automticamente al utilizar la instruccin SELECTINTO. La estructura de esta instruccin es la siguiente:
SELECT columna1, , columnaN INTO variable1, , variableN FROM <tablas/Vistas> WHERE <Predicados>

Esta instruccin es una consulta SELECT habitual, donde el resultado de la consulta se almacena en un conjunto de variables que hayan sido declaradas en el bloque PL/SQL. Hay que asegurarse que la consulta devuelve una y solo una fila (mnimo una fila y mximo una fila). Si no se cumple esta restriccin el cursor implcito lanzar una excepcin en cada caso: NO_DATA_FOUND. Se lanza si la consulta devuelve un resultado vaco. TOO_MANY_ROWS. Se lanza si la consulta devuelve ms de una fila. 3.1.1. Atributos de los cursores implcitos Los atributos de los cursores implcitos devuelven informacin relativa a la ejecucin de una instruccin SQL INSERT, DELETE, UPDATE o SELECTINTO. Para los cursores implcitos los valores siempre hacen referencia a la ltima instruccin que se haya ejecutado. Se pueden acceder a los atributos de un cursor implcito utilizando la sintaxis SQL%<atributo>, ejemplo:
DELETE FROM EMPLEADOS WHERE emp_id = mi_empleado; IF SQL%FOUND THEN - La operacin de borrado ha tenido xito ... END IF;

Los atributos que estn disponibles para los cursores implcitos tienen valor una vez que se ha ejecutado la instruccin SQL correspondiente, hasta ese momento su valor es NULL. Los atributos disponibles y su significado es el siguiente: %FOUND. Tras ejecutar una instruccin INSERT, DELETE o UPDATE que afecte a una o ms instrucciones o una SELECTINTO que devuelva una o ms filas %FOUND devuelve TRUE. En otro caso devuelve FALSE. %ISOPEN. Devuelve FALSE siempre para cursores implcitos. %NOTFOUND. Es el opuesto de %FOUND.

%ROWCOUNT. Devuelve el nmero de filas afectadas por una instruccin INSERT, DELETE o UPDATE. Si SELECTINTO devuelve ms de una fila se lanza la excepcin TOO_MANY_ROWS y %ROWCOUNT devuelve 1.

3.2. Cursores explcitos


Los cursores explcitos son utilizados para procesar el resultado de consultas que devuelven un nmero indefinido de filas (i.e. 0, 1 o 1). Los pasos necesarios para utilizar cursores explcitos son: 1. Declarar la variable cursor e inicializacin con una consulta (puede estar parametrizada), declaracin de variables donde se almacenarn los resultados del cursor. 2. Abrir el cursor (OPEN). 3. Lectura de las filas una a una y procesamiento de las mismas (FETCH). Habitualmente se implementa como un bucle sobre el cursor. 4. Cierre del cursor (CLOSE). Ejemplo: Dada la tabla MOTOS(MARCA,MODELO,CC,AO,EXISTENCIAS), muestra por pantalla la marca y modelo de las motocicletas de al menos 500 cc.
DECLARE CURSOR cmotos IS SELECT marca, modelo FROM motos WHERE cc>=500; -- Variables auxiliares para el cursor Xmarca motos.marca%TYPE; Xmodelo motos.modelo%TYPE; BEGIN OPEN cmotos; FETCH cmotos INTO xmarca, xmodelo; WHILE cmotos%FOUND LOOP DBMS_OUTPUT.PUT_LINE(xmarca || ' ' || xmodelo); FETCH cmotos INTO xmarca, xmodelo; END LOOP; CLOSE cmotos; END; / /* Cuerpo alternativo con bucle LOOP BEGIN OPEN cmotos; LOOP FETCH cmotos INTO xmarca, xmodelo; EXIT WHEN cmotos%NOTFOUND; DBMS_OUTPUT.PUT_LINE(xmarca || ' ' || xmodelo); END LOOP; CLOSE cmotos; END; */

Existe una versin especial de bucle FOR denominada "Cursor FOR LOOP" para iterar sobre un cursor explcito:
-- Cursor FOR LOOP DECLARE CURSOR cmotos IS SELECT marca, modelo FROM motos WHERE cc>=500; -- No necesitamos declarar variables de almacenaje.

BEGIN FOR motos_reg IN cmotos LOOP DBMS_OUTPUT.PUT_LINE(motos_reg.marca || ' ' || motos_reg.modelo); END LOOP; -- No hace falta ni abrir ni cerrar el cursor. END; /

Para declarar las variables donde se almacenarn los valores que se obtendrn del cursor es habitual hacer uso de de %TYPE y %ROWTYPE para no tener que especificar explcitamente el tipo de la variable, de modo que: %TYPE se utiliza para obtener el tipo de una columna concreta de alguna de las tablas/vistas que est involucrada en la consulta que forma parte del cursor. %ROWTYPE se utiliza para obtener el tipo de una fila completa de alguna de las tablas/vistas que est involucrada en la consulta que forma parte del cursor. Habitualmente se utiliza si el cursor se inicializa con una consulta SELECT *. Como se ha mencionado, un cursor puede parametrizarse, de modo que el parmetro formal puede formar parte de la consulta que inicializa el cursor. Los parmetros actuales para el cursor se especifican a la hora de abrir el cursor o el cursor puede utilizar el valor por defecto que se haya especificado.
DECLARE /* El cursor tiene un parmetro cilindrada que puede tener un valor por defecto. */ CURSOR cmotos (cilindrada INTEGER DEFAULT 125) IS SELECT marca, modelo FROM motos WHERE cc>=cilindrada; BEGIN /* Cuando se abre el cursor se puede dar un valor especfico al parmetro o dejar que se utilice el valor por defecto. */ OPEN cmotos(500); FETCH cmotos INTO xmarca, xmodelo; WHILE cmotos%FOUND LOOP DBMS_OUTPUT.PUT_LINE(xmarca || ' ' || xmodelo); FETCH cmotos INTO xmarca, xmodelo; END LOOP; CLOSE cmotos; END; / /* Cuerpo alternativo con bucles Cursor FOR LOOP BEGIN -- El parmetro actual se puede especificar en el IN del bucle FOR motos_reg IN cmotos(500) LOOP DBMS_OUTPUT.PUT_LINE(motos_reg.marca || ' ' || motos_reg.modelo); END LOOP; END; */

3.2.1. Atributos de los cursores explcitos Al igual que con los cursores implcitos, los cursores explcitos tienen una serie de atributos asignados como los atributos %FOUND y %NOTFOUND utilizados en el apartado anterior. Los atributos disponibles en un cursor explcito y su significado es el siguiente:

%FOUND. Desde que el cursor es abierto hasta que se obtiene la primera fila el valor de %FOUND es NULL. Tras obtener una fila %FOUND devuelve TRUE si realmente se ha podido obtener una fila FALSE en otro caso. %ISOPEN. Devuelve TRUE si el cursor se ha abierto y FALSE en otro caso. %NOTFOUND. Es el opuesto de %FOUND. %ROWCOUNT. Antes de que se obtenga alguna fila %ROWCOUNT devuelve el valor 0, despus de que se haya obtenido alguna fila devuelve el nmero de filas que se han obtenido hasta el momento (es decir el nmero de FETCH exitosas hasta el momento).

3.3. Referencias del Apartado


Ver Cursors en [1]. Ver Using Cursors within Applications en [2]. Ver Cursors en [4]. Ver Managing Cursors, Using Cursors FOR Loops y Using Cursors Variables en [4].

4.

Procedimientos, funciones y paquetes

En el lenguaje PL/SQL es posible definir subprogramas (procedimientos y funciones) similares a los subprogramas en los lenguajes. Adicionalmente es posible crear agrupaciones de procedimientos, funciones y variables que son denominadas paquetes. De manera simple, los subprogramas pueden verse como bloques PL/SQL con nombre que pueden incluir adicionalmente una serie de parmetros de entrada y salida.

4.1. Procedimientos
La sintaxis genrica para definir un procedimiento es:
PROCEDURE <nombre> [(<parmetrol>, ... <parmetroN>)] IS [<declaraciones de variables, constantes, ..>] BEGIN sentencias; [EXCEPTION manejadores de excepciones;] END [<nombre>];

Los parmetros de un procedimiento se especifican indicando su nombre, modo y tipo. El nombre del parmetro sigue las mismas reglas que los identificadores, el modo especifica si el parmetro es de entrada (IN, valor por defecto), salida (OUT) o entrada/salida (IN OUT) y finalmente el tipo especifica el tipo de datos del parmetro (NOTA: no puede ser un subtipo). La sintaxis general para definir los parmetros formales de un procedimiento queda del siguiente modo:
<nombre> [IN | OUT | IN OUT] <tipo>

4.2. Funciones
La sintaxis genrica para definir una funcin queda es:
FUNCTION <nombre> [(<parmetrol>, ... <parmetroN>)] RETURN <tipo> IS [<declaraciones de variables, constantes, ..>] BEGIN sentencias; RETURN v; -- La funcin devuelve el valor de la variable v. [EXCEPTION manejadores de excepciones;]

END [<nombre>];

Al igual que los procedimientos, las funciones pueden especificar parmetros formales. Aunque el lenguaje PL/SQL permite especificar los parmetros de una funcin con los modos OUT o IN OUT, siguiendo las buenas prcticas de programacin de los lenguajes procedimientales, una funcin no utiliza los modos OUT o IN OUT para sus parmetros formales. Adicionalmente si se desea que la funcin pueda ser utilizada en una instruccin SQL es necesario que la implementacin de la funcin siga las siguientes reglas para evitar los efectos laterales: Si la funcin se utiliza en una sentencia SELECT la funcin no debe modificar ninguna tabla. Si la funcin es llamada desde una sentencia INSERT, UPDATE, o DELETE la funcin no debe modificar ninguna de las tablas que se estn modificando con la sentencia. Si la funcin es llamada desde cualquier sentencia, la funcin no puede incluir ninguna sentencia de control de transaccin, gestin de sesin, sentencia DCL o sentencia DDL.

4.3. Uso de procedimientos y funciones


Al igual que las variables, es necesario definir los procedimientos y funciones antes de poder utilizarlos. Los procedimientos y funciones pueden definirse al final de la seccin de declaraciones de un bloque PL/SQL, de modo que estos procedimientos y funciones pueden ser utilizados en el cuerpo del bloque. Una vez declarados, los procedimientos pueden se llamados desde el cuerpo del bloque PL/SQL correspondiente. Adems las funciones tambin pueden ser llamadas o bien desde el cuerpo de un bloque PL/SQL o como parte de una sentencia SQL.
DECLARE ... variable ...; PROCEDURE procedimiento (...) IS BEGIN ... END; FUNCTION funcion (...) RETURN ... IS BEGIN ... END; BEGIN procedimiento(...); ... variable := funcion(...); ... END;

4.4. Subprogramas almacenados


Los procedimientos y funciones definidos en los apartados anteriores residen habitualmente en ficheros de texto (ficheros .sql). Sin embargo, es posible crear procedimientos y funciones que estn almacenados en el servidor. Los procedimientos y funciones almacenados tiene la ventaja de que pueden ser llamados desde las aplicaciones cliente, por ejemplo, utilizando el lenguaje Java, sin necesidad de conocer la implementacin del procedimiento o funcin.

Para crear un procedimiento o funcin almacenado, simplemente hay que anteponer CREATE a la definicin del procedimiento o funcin. Si aadimos OR REPLACE se reemplaza el procedimiento o funcin almacenada que existiera en el servidor.
CREATE [OR REPLACE] PROCEDURE ... CREATE [OR REPLACE] FUNCTION ...

Para poder crear un procedimiento o funcin almacenada es necesario que el usuario tenga asignado el privilegio de sistema CREATE PROCEDURE. Tambin es posible recompilar un subprograma almacenado utilizando la sentencia ALTER:
ALTER FUNCTION <nombre> COMPILE; ALTER PROCEDURE <nombre> COMPILE; ALTER PACKAGE <nombre> COMPILE SPECIFICATION; - Recompila la declaracin; BODY; - Recompila la implementacin del paquete PACKAGE; - Recompila la declaracin y la implementacin

Finalmente para eliminar un subprograma almacenado se utiliza la sentencia DROP con


DROP FUNCTION <nombre>; DROP PROCEDURE <nombre>; DROP PACKAGE [BODY] <nombre>; -- Si se especifica BODY solo se elimina la implementacin.

Para evitar problemas con la creacin de funciones y procedimientos almacenados es recomendable primero probar los procedimientos y funciones en un bloque PL/SQL annimo (siguiendo la estructura descrita en 4.3). Adems otro problema de crear procedimientos y funciones almacenadas es que no se muestran directamente los errores de compilacin, sino que es necesario utilizar la instruccin SHOW ERRORS.

4.5. Paquetes
De manera similar al concepto de mdulo en los lenguajes procedimentales, es posible definir paquetes en PL/SQL que permiten agrupar variables, procedimientos y funciones PL/SQL. Los paquetes son subprogramas almacenados, de modo que no se puede no se pueden definir en la seccin de declaraciones de un bloque PL/SQL para probarlos. Por tanto, es recomendable probar los procedimientos y funciones del paquete por separado antes de crear el paquete. La creacin de un paquete se divide en dos partes: Especificacin. La especificacin representa la seccin de declaraciones del paquete. Esta seccin incluir la declaracin de variables del paquete y la declaracin (solo cabeceras) de procedimientos y funciones del paquete. Implementacin. Se especifican los bloques PL/SQL para implementar los procedimientos y funciones. Adicionalmente tambin se pueden declarar variables que solo sern accesibles desde la implementacin del paquete. La estructura genrica para la declaracin de un paquete es:
CREATE [OR REPLACE] PACKAGE <nombre> IS /* Declaraciones pblicas: - variables, constantes, excepciones, cursores. - cabeceras de procedimientos y funciones.*/ END <nombre>; /

La estructura genrica para la implementacin de un paquete es:

CREATE [OR REPLACE] PACKAGE BODY <nombre> IS -- Declaraciones privadas <Implementacin de procedimientos y funciones pblicas> [BEGIN <cdigo de inicializacin> -- Se ejecuta la 1 vez que se invoca el paquete] END <nombre>; /

Una vez que se ha creado un paquete, para acceder a los elementos del paquete simplemente hay que anteponer el nombre del paquete al del objeto que se desea acceder.
BEGIN nombre_paquete.procedimiento(...); END; /

Un ejemplo mnimo de declaracin de paquete es el siguiente:


CREATE OR REPLACE PACKAGE paqueteSimple IS constante CONSTANT INTEGER := 0; PROCEDURE holaMundo; END paqueteSimple; /

Finalmente la implementacin del paquete mnimo es la siguiente:


CREATE OR REPLACE PACKAGE BODY paqueteSimple IS var_interna INTEGER; PROCEDURE holaMundo IS BEGIN DBMS_OUTPUT.PUT_LINE('Hola mundo'); END holaMundo; BEGIN var_interna := 0; DBMS_OUTPUT.PUT_LINE('Inicializando paquete'); END paqueteSimple; /

4.5.1. Paquetes preinstalados en Oracle Oracle incorpora una extensa librera de funcionalidades preinstaladas en forma de paquetes (ver [5] para documentarse de todos los paquetes). Algunos de los paquetes incorporados en el servidor para el desarrollo de aplicaciones son: DBMS_OUTPUT. Permite gestionar el buffer para intercambio de informacin con procedimientos, funciones o el terminal del intrprete. DBMS_MVIEW. Permite gestionar las vistas materializadas, por ejemplo, para poder refrescar una vista materializada. DBMS_PIPE. Permite la comunicacin entre sesiones. Una sesin es una conexin de una aplicacin cliente (como SQL*Plus) al servidor de base de datos para un usuario especfico. DBMS_ALERT. Permite para enviar notificar alertas a los usuarios. DBMS_LOCK y DBMS_TRANSACTION. Permiten para gestionar bloqueos y transacciones. Algunos paquetes incorporados en el servidor para la gestin del servidor son: DBMS_SESSION. Permite gestionar las sesiones al DBA. DBMS_SYSTEM. Permite establecer eventos utilizados para la depuracin.

DBMS_SPACE y DBMS_SHARED_POOL. Permite obtener informacin del espacio y reservar recursos en el pool compartido. DBMS_JOB. Permite planificar trabajos en el servidor.

4.5.2. Paquete DBMS_OUTPUT Este paquete incluye procedimientos y funciones para gestionar el buffer de intercambio de informacin de procedimientos y funciones con la consola del intrprete. Las funciones ms relevantes que se incluyen dentro del paquete son: PUT. Coloca una cadena de caracteres en el buffer. PUT_LINE. Coloca una cadena en el buffer como una nueva lnea NEW_LINE. Inserta un salto de lnea en buffer (despus de un PUT) GET_LINE. Obtiene una lnea del buffer. GET_LINES. Obtiene varias lneas del buffer. Para activar el eco del buffer (salida por consola) en SQL*Plus (SQL*Worksheet y Developer incluidos), se debe introducir la orden:
SET SERVEROUTPUT ON [FORMAT WRAPPED] [SIZE <tamao>] -- Ejemplo SET SERVEROUTPUT ON SIZE 10000

La instruccin SET SERVEROUTPUT ON activa el eco de la sesin durante la sesin actual. Es recomendable que esta instruccin sea la primera instruccin de nuestro programa PL/SQL.

4.6. Referencias del apartado


Ver Using Procedures and Packages en [2]. Ver PL/SQL Subprograms en [4]. Ver PL/SQL Packages en [4].

5.

Transacciones

Una transaccin es una unidad de trabajo que incluye una o ms instrucciones SQL que son ejecutadas por un nico usuario. En Oracle, y segn el estndar SQL 92, una transaccin comienza con la primera instruccin SQL de usuario ejecutable. Una transaccin termina cuando es confirmada o rechazada explcitamente por el usuario. Las transacciones permiten a los usuarios garantizar modificaciones consistentes sobre los datos siempre que las instrucciones SQL de la transaccin estn agrupadas lgicamente. Una transaccin debe contener las instrucciones SQL necesarias para mantener la consistencia de la BBDD, de modo que los datos de tablas referenciadas estn en un estado consistente antes y despus de una transaccin. El lenguaje PL/SQL permite controlar la transaccin activa mediante las instrucciones: COMMIT. Confirma la transaccin activa y por tanto se realizan todas las modificaciones pendientes en la BBDD. ROLLBACK [<id_savepoint>]. Rechaza la transaccin activa y por tanto se deshacen los cambios realizados en la transaccin. Si se especifica <id_savepoint> se rechanzan los cambios hasta el punto marcado en la transaccin con identificador <id_savepoint>. SAVEPOINT <id_savepoint>. Permite marcar un punto de la transaccin con el identificador <id_savepoint>. Adems tambin es controlar el comportamiento de la transaccin con el comando SET TRANSACTION, algunos parmetros para este comando son:

READ ONLY. Configura la transaccin en modo slo lectura (no se permiten modificaciones de la BBDD) y se consigue el nivel de aislamiento lectura repetible. ISOLATION LEVEL (SERIALIZABLE | READ COMMITED). Configura la transaccin en los niveles de aislamiento serializable o lectura comprometidas respectivamente.

-- Finaliza la transaccin previa COMMIT; -- Configura la transaccin como solo lectura SET TRANSACTION READ ONLY; SELECT ... FROM Empleados WHERE ... SELECT ... FROM Departamento WHERE ... /*Obtenemos los mismos resultados que la consulta anterior ya que las transacciones de solo lectura obtienen el nivel de aislamiento de lectura repetible */ SELECT ... FROM Empleados WHERE ... COMMIT; -- Finaliza la transaccin aunque no se modifique la BBDD

5.1. Referencias del apartado


Ver User Processes Overview en [1]. Ver Transactions Overview en [1]. Ver Data Concurrency and Consistency en [1]. Ver Transaction Control Statements en [1]. Ver Control of Transactions en [1]. Ver Transaction Management en [1]. Ver Data Concurrency and Consistency en [1]. Ver How Oracle Processes SQL Statements en [2]. Ver Transaction Control en [4]. Ver Overview of Transaction Processing in PL/SQL en [4]. Ver Retrying a Transaction en [4].

6.

Disparadores

Los disparadores son bloques PL/SQL almacenados que son ejecutados automticamente cuando una tabla es modificada a travs de las instrucciones DML INSERT, DELETE y UPDATE. Aunque no se describe en esta seccin, Oracle permite crear disparadores para gestionar eventos relacionados con acciones de usuario sobre la BBDD (ejecucin de instrucciones DDL) o incluso eventos del servidor (arranque o parada del servidor). Los disparadores pueden ser utilizados para mltiples finalidades, algunas de ellas son: Gestin de atributos derivados y redundancias en tablas. Hacer respetar restricciones complejas de seguridad. Gestin de la integridad de los datos de la tabla, por ejemplo, hacer cumplir las DF asociadas a una tabla. Proporcionar un mecanismo de auditora de las tablas. Actualizaciones en cascada (Oracle no tiene ON UPDATE CASCADE para las FOREIGN KEY). Aunque los disparadores son muy verstiles, hay que utilizar solo cuando sean necesarios ya que el uso excesivo de disparadores puede dificultar el mantenimiento y gestin. Ntese que cuando se ejecuta un disparador, las instrucciones SQL incluidas en el bloque PL/SQL del mismo disparador pueden disparar la ejecucin de otro disparador distinto. Un disparador est compuesto de tres partes bsicas:

Declaracin de la instruccin o instrucciones que generarn un evento que dispare el disparador. Adicionalmente se especifica el instante en el que se ejecutar el disparador. Una restriccin. Es una expresin Booleana que debe ser cierta para que se ejecute el disparador. La restriccin habitualmente est asociada a un disparador a nivel de fila. Una accin. Al igual que los subprogramas almacenados, la accin de un disparador puede contener instrucciones PL/SQL incluyendo la llamada a procedimientos y funciones almacenadas. Ejemplo de disparador:
/** * Disparador que vigila el stock del almacen. * Si el stock est por debajo del nivel mnimo se aade un nuevo * pedido (si no se ha solicitado ya). */ CREATE OR REPLACE TRIGGER vigilar_almacen /** * Evento de disparo del disparador. * El disparador se ejecuta despus de modificarse la columna 'stock' * de la tabla 'almacen' cuando se ha ejecutado una instruccin * UPDATE. */ AFTER UPDATE OF stock ON almacen /** * Restriccin de aplicacin del disparador. * El disparador slo se ejecuta si el stock resultante del UPDATE * est por debajo del mnimo. */ FOR EACH ROW WHEN (new.stock < new.stock_minimo) -- Disparador a nivel de fila /** * Accin del disparador. * Si los disparadores son del tipo fila (FOR EACH ROW) el bloque * PL/SQL puede acceder a los valores de las filas que son procesadas * por el disparador. */ DECLARE pedido_realizado NUMBER; BEGIN SELECT count(*) INTO pedido_realizado FROM pedidos WHERE codigo_producto = :NEW.codigo_producto; IF pedido_realizado = 0 THEN INSERT INTO pedidos VALUES (:NEW.codigo_producto, :NEW.pedido_minimo, SYSDATE); END IF; END;

6.1. Tipos de disparadores


Oracle permite la creacin de los siguientes tipos de disparadores: Disparadores a nivel de fila (FOR EACH ROW). Disparadores a nivel de instruccin. Disparadores INSTEAD OF.

6.1.1. Disparadores a nivel de fila (FOR EACH ROW) Los disparadores a nivel de fila (declarados FOR EACH ROW) ejecutan la accin asociada al disparador un nmero de veces igual al nmero de filas afectadas por la instruccin que ha generado el evento de disparo. Por ejemplo, una instruccin UPDATE puede modificar mltiples filas de una tabla, de modo que la accin del disparador se ejecuta una vez por cada una de las filas afectadas por la instruccin UPDATE. Los disparadores a nivel de fila son tiles cuando el bloque PL/SQL asociado a la accin del disparador depende de los valores proporcionados por la instruccin que genera el evento, por ejemplo, para generar valores para atributos derivados. 6.1.2. Disparadores a nivel de instruccin Los disparadores a nivel de instruccin ejecutan la accin asociada al disparador una vez por instruccin independientemente del nmero de filas afectadas por la instruccin. Los disparadores a nivel de instruccin son tiles en aquellos casos en los que el bloque PL/SQL asociado no dependa de los datos que proporciona la instruccin que ha generado el evento, en particular este tipo de disparadores pueden ser utilizados para: Realizar tareas de auditora. Realizar comprobaciones complejas de seguridad. 6.1.3. Disparadores INSTEAD OF Los disparadores INSTEAD OF ofrecen un mecanismo transparente para modificar vistas utilizando instrucciones DML INSERT, UPDATE y DELETE. Estos disparadores son denominados "en vez de" ya que Oracle ejecuta la accin asociada al disparador en vez de la instruccin que ha generado el evento.

6.2. Diseo, creacin y gestin de disparadores


Es recomendable tener en cuenta los siguientes criterios a la hora de definir disparadores: Los disparadores deben ser utilizados para garantizar que siempre que se ejecute una instruccin se ejecuten las acciones asociadas al disparador. Los disparadores deben utilizarse solo si Oracle no ofrece otro mecanismo para realizar la misma operacin. Por ejemplo, un disparador no debera de crearse para realizar tareas que se pueden llevar a cabo automticamente como la gestin de la integridad referencial si se puede utilizar la restriccin FOREIGN KEY. Limitar el tamao del disparador. Si la extensin del disparador es > 60 lneas, es recomendable crear un procedimiento almacenado y llamarlo desde la accin del disparador. Para crear un disparador es necesario que el usuario tenga asignado el permiso CREATE TRIGGER.

La sintaxis genrica para crear un disparador es la siguiente:


CREATE [OR REPLACE] TRIGGER <nombre> /** * Controla cuando se ejecuta la accin del disparador: * - BEFORE: la accin se ejecuta antes que la propia instruccin. * - AFTER: la accin se ejecuta despus de la propia instruccin. */ { BEFORE | AFTER } /** * Instruccin o instrucciones que provocan la ejecucin del * disparador. * - En el caso de la instruccin UPDATE se puedes especificar * una lista con las columnas especficas monitorizar. */ { DELETE | INSERT | UPDATE [OF column [,column] ...] } [OR { DELETE | INSERT | UPDATE [OF column [,column] ...] } ] ... /** * Tabla a la que se asocia el disparador */ ON nombre_tabla /** * Especificacin de disparador a nivel de fila. * En este caso tiene sentido especificar una condicin que debe * debe ser cierta para que la accin del disparador se ejecute. * - La condicin pueden hacer referencia a las variables :OLD y :NEW. * - La condicin no puede contener subconsultas. * - La condicin se evala por cada fila afectada. */ [FOR EACH ROW [WHEN (<condicin>)]] DECLARE ... BEGIN -- Cdigo asociado a la accin del disparador END;

En ocasiones, por ejemplo, al cargar datos con SQL*Loader, puede ser necesario desactivar algn disparador concreto o desactivar los disparadores asociados a una tabla:
ALTER TRIGGER <nombre_disparador> {DISABLE | ENABLE}; ALTER TABLE <nombre_tabla> {ENABLE | DISABLE} ALL TRIGGERS;

Es posible consultar los disparadores que ha creado un usuario a travs de la vista USER_TRIGGERS del diccionario de datos, por ejemplo:
SELECT trigger_type, table_name, triggering_event FROM USER_TRIGGERS WHERE trigger_name = '<nombre del disparador>';

Al igual que los subprogramas almacenados, tambin es posible eliminar un disparador:


DROP TRIGGER <nombre>;

6.2.1. Implementacin de la accin de un disparador El bloque PL/SQL asociado a la accin de un disparador tiene algunas restricciones y extensiones respecto a un bloque PL/SQL normal. Las restricciones asociadas a la implementacin de un disparador son:

No es posible acceder a la tabla asociada al disparador: error de tablas mutantes (ORA-04091). Esta restriccin aplica a disparadores del tipo FOR EACH ROW y a disparadores de instruccin ejecutados como resultado de un modificador DELETE CASCADE. No se admiten sentencias de control de transacciones (COMMIT, etc.). Adems, los procedimientos que sean llamados desde el bloque PL/SQL tampoco pueden utilizar instrucciones de control de transaccin. No es posible modificar informacin de los campos de la clave primaria. No es posible declarar variables de tipo LONG. Adicionalmente puesto que un mismo disparador puede asociarse a varios eventos producidos por diferentes instrucciones SQL, es posible diferenciar la fuente del evento en el cuerpo del disparador utilizando los predicados INSERTING, UPDATING y DELETING, ejemplo:
IF INSERTING THEN op := 'I'; ELSIF UPDATING THEN op := 'U'; ELSE op := 'D'; END IF;

Las variables :NEW y :OLD Los disparadores a nivel de fila pueden hacer uso de un par de variables :NEW y :OLD en el bloque PL/SQL asociado que permiten acceder a los valores nuevos y viejos de las filas que ha sido afectadas como resultado de la ejecucin de la instruccin. Las dos variables permiten acceder a todas las columnas de las filas afectadas (como si tuvieran tipo tabla_asociada%ROWTYPE). Sin embargo, dependiendo de la instruccin que haya provocado la ejecucin del disparador, alguna de las variables puede no tener sentido: Instruccin INSERT. La variable :NEW contiene los nuevos valores para cada fila afectada. :OLD contiene valores NULL. Instruccin UPDATE. La variable :NEW contiene los valores nuevos para cada fila afectada. La variable :OLD contiene los valores viejos para cada fila afectada. La instruccin DELETE. La variable :NEW contiene valores NULL. La variable :OLD contiene los viejos valores de cada fila afectada. Condiciones de error y excepciones en el cuerpo de un disparador Si una excepcin predefinida o definida por el usuario es lanzada durante la ejecucin de la accin de un disparador, todos los efectos de las instrucciones ejecutadas como parte del disparador y la instruccin que ha provocado la ejecucin del disparador son rechazadas. Por tanto aunque no se puedan utilizar instrucciones de control de transacciones, el lanzamiento de una excepcin provoca que la transaccin activa sea rechazada. Los disparadores son habitualmente utilizados como mecanismo para gestionar la integridad de los datos de un modo no declarativo ya que pueden ser configurados para ejecutar automticamente un bloque PL/SQL cuando se ejecuta una instruccin que modifica la BBDD como INSERT, UPDATE o DELETE. Las excepciones de usuario presentadas en la seccin 2.6.2 son particularmente tiles en los disparadores para controlar la transaccin en la que se ejecuta el disparador.

Aunque no se permiten utilizar las instrucciones COMMIT o ROLLBACK en los disparadores, si en el cuerpo del disparador se lanza una excepcin la transaccin activa es abortada. 6.2.2. Creacin de disparadores INSTEAD OF Los disparadores INSTEAD OF son un caso particular de disparadores a nivel de fila. Algunas restricciones adicionales para los disparadores INSTEAD OF son: Solo pueden ser aplicados sobre vistas. No se pueden especificar las opciones BEFORE y AFTER en la declaracin del disparador. Si la vista tiene asociada una restriccin CHECK, sta no se comprueba cuando las inserciones o modificaciones se realicen en el disparador. La accin del disparador es la encargada de realizar la comprobacin.
CREATE [OR REPLACE] TRIGGER <nombre> INSTEAD OF { DELETE | INSERT | UPDATE } [OR { DELETE | INSERT | UPDATE } ] ... ON nombre_vista FOR EACH ROW DECLARE ... BEGIN -- Cdigo asociado a la accin del disparador END;

6.3. Ejecucin de disparadores


Una nica instruccin SQL puede potencialmente disparar hasta cuatro tipos de disparadores: Disparador a nivel de fila BEFORE Disparador a nivel de instruccin BEFORE. Disparador a nivel de fila AFTER. Disparador a nivel de instruccin AFTER. Adicionalmente la instruccin que ha provocado la ejecucin del disparador o las instrucciones ejecutadas como parte de la accin del disparador pueden causar la comprobacin de una o ms restricciones de integridad. Adems, como se ha mencionado antes, las instrucciones de la accin de un disparador pueden provocar que se ejecuten otros disparadores. Algunas consideraciones generales que es necesario tener en cuenta cuando se trabaja con disparares son: Al igual que con las instrucciones SQL, no se puede suponer el orden en el que se procesan las filas en un disparador a nivel de fila. No se puede suponer el orden de ejecucin de los disparadores asociados al mismo elemento de datos e instruccin. El modelo de ejecucin utilizado para mantener el orden correcto de ejecucin de mltiples disparadores y comprobaciones de restricciones de integridad para una instruccin y elementos de datos es el siguiente: 1. Se ejecutan todos los disparadores a nivel de instruccin del tipo BEFORE asociados a la instruccin. 2. Se itera sobre todas las filas afectadas por la instruccin SQL. 3. Se ejecutan todos los disparadores a nivel fila del tipo BEFORE asociados a la instruccin.

1. Bloquea, modifica la fila y lleva a cabo las comprobaciones de restricciones de integridad (los bloqueos no son liberados hasta el final de la transaccin). 4. Se ejecutan todos los disparadores a nivel de fila del tipo AFTER asociados a la instruccin. 5. Se completa la comprobacin de todas las restricciones de integridad pospuestas (marcadas como DEFERRABLE). 6. Se ejecutan todos los disparadores a nivel de instruccin del tipo AFTER asociados a la instruccin.

6.4. Referencias del Apartado


Ver Triggers en [1]. Ver Using Triggers en [2]. Ver How Oracle Enforces Data Integrity en [1]. Ver Deferred Constraint Checking [1].

7.
[1] [2] [3] [4] [5] [6] [7] [8]

Referencias
Oracle9i Database Concepts, Release 2 (9.2). Disponible en: librero, oracle. Application Developer's Guide Fundamentals Release 2 (9.2).Disponible en: librero, oracle. Oracle9i SQL Reference, Release 2 (9.2). Disponible en: librero, oracle. PL/SQL User's Guide and Reference, Release 2 (9.2). Disponible en: librero, oracle. Oracle9i Supplied PL/SQL Packages and Types Reference, Release 2 (9.2). Disponible en: librero, oracle. SQL*Plus Getting Started, Release 9.0.1 for Windows. Disponible en: librero oracle. SQL*Plus User's Guide and Reference, Release 9.2. Disponible en: librero, oracle. Oracle9i Database Reference, Release 2 (9.2). Disponible en: librero, oracle.

También podría gustarte