Вы находитесь на странице: 1из 41

FEBRERO - 2009

CURSO BASE DE DATOS

PL / SQL

Resumen PL/SQL III


Resumen PL/SQL III

Curso Base de Datos


Pgina 1

Bloques PL/SQL
Un bloque PL/SQL es la unidad bsica de todo programa. Todos los programas PL/SQL estn compuestos por bloques, los cuales pueden ser secuenciales o anidados.

Los tipos de bloques son:

Bloques annimos Se construyen generalmente de manera dinmica y slo se ejecutan una vez.

Bloques con nombre Son como los bloques annimos, pero tienen una etiqueta que le da al bloque un nombre.

Subprogramas Son procedimientos, funciones y paquetes que son almacenados en base de datos y se ejecutan cuando son invocados.

Disparadores (Triggers) Son bloques con nombre que son almacenados en la base de datos. Son ejecutados implcitamente cuando cierto evento ocurre.

Resumen PL/SQL III

Pgina 2

Procedimientos
Un procedimiento es un bloque PL/SQL al que se le asigna un nombre. Un procedimiento se crea para que realice una determinada tarea de gestin. Los procedimientos son compilados y almacenados en la base de datos. Gracias a ellos se consigue una reutilizacin eficiente del cdigo, ya que se puede invocar al procedimiento las veces que haga falta desde otro cdigo o desde una herramienta de desarrollo como Oracle Developer. Una vez almacenados pueden ser modificados de nuevo.

Crear procedimientos
CREATE [OR REPLACE] PROCEDURE <NOMBRE_PROCEDIMIENTO> [ ( <PARAMETRO_1> [IN | OUT | IN OUT] <TIPO_1> , . <PARAMETRO_N> [IN | OUT | IN OUT] <TIPO_N>) ] <CUERPO_PROCEDIMIENTO> IS

La opcin REPLACE hace que si ya existe un procedimiento con ese nombre, se reemplaza el anterior con el que se crea ahora. Los parmetros son la lista de variables que necesita el procedimiento para realizar su tarea; se indica el tipo de los mismos, pero no su tamao (VARCHAR2 y no VARCHAR2(50)). En los parmetros, el modo pueden ser las palabras IN, OUT o IN OUT. La palabra DECLARE no se utiliza, la seccin de declaraciones figura tras las palabras IS o AS. <CUERPO_PROCEDIMIENTO> es un bloque PL/SQL que contiene el cdigo para el procedimiento.

Resumen PL/SQL III

Pgina 3

CREATE OR REPLACE PROCEDURE SALUDO IS BEGIN DBMS_OUTPUT.PUT_LINE('ALMACENES VISIN FUTURA') ; END;

Para ejecutar este procedimiento desde la lnea de comando se usa la instruccin:

BEGIN SALUDO; END;

CREATE OR REPLACE PROCEDURE VISUALIZAR(TEXTO IN VARCHAR2) IS BEGIN DBMS_OUTPUT.PUT_LINE(TEXTO) ; END; /

BEGIN VISUALIZAR('Empresa de Marketin Promocional'); VISUALIZAR('Logstica propia'); END; /

Borrar procedimientos
El comando DROP PROCEDURE elimina el procedimiento indicado. DROP PROCEDURE <NOMBRE_PROCEDIMIENTO>

Resumen PL/SQL III

Pgina 4

Funciones
Las funciones son similares a los procedimientos. La diferencia es que las funciones al menos deben de regresar un valor.

Crear funciones

CREATE [OR REPLACE] FUNCTION <NOMBRE_FUNCION> [ ( <PARAMETRO_1> [IN | OUT | IN OUT] <TIPO_1> , . <PARAMETRO_N> [IN | OUT | IN OUT] <TIPO_N>) ] RETURN <TIPO_RETORNO> IS <CUERPO_FUNCION>

Donde <CUERPO_FUNCION> es un bloque PL/SQL que contiene el cdigo para la funcin, y dentro de ste debe estar la instruccin RETURN. Toda funcin ha de devolver un valor, lo cual implica utilizar la instruccin RETURN seguida del valor que se devuelve.

CREATE OR REPLACE FUNCTION MULTIPLICAR(N1 NUMBER,N2 NUMBER ) RETURN NUMBER IS TOT NUMBER; BEGIN TOT:= N1 * N2; RETURN TOT; END; /

La llamada a una funcin debe de ser parte de una instruccin SQL. As, una manera de ejecutar la funcin MULTIPLICAR podra ser:
SELECT MULTIPLICAR(3,5) FROM DUAL;

Resumen PL/SQL III

Pgina 5

SELECT PRECIO_VENTA_ART "PRECIO 2007", MULTIPLICAR(PRECIO_VENTA_ART ,1.05) "PRECIO 2008" FROM TARTICULO;

DECLARE PRECIO_UNITARIO NUMBER :=25 ; UNIDADES NUMBER :=8 ; BEGIN VISUALIZAR(MULTIPLICAR(PRECIO_UNITARIO,UNIDADES)) ; END;

DESC MULTIPLICAR;

Borrar funciones
El comando DROP FUNCTION elimina la funcin indicada. DROP FUNCTION <NOMBRE_FUNCION>

Resumen PL/SQL III

Pgina 6

MODOS DE LOS

PARMETROS

IN - El valor del parmetro real se pasa al procedimiento cuando se produce la llamada al mismo. Dentro del procedimiento, el parmetro formal se comporta como una constante (Solo lectura). Cuando el procedimiento finaliza y devuelve el control al entorno en el que se produjo la llamada, el parmetro real no se modifica.

OUT - Se ignora cualquier valor que el parmetro real pueda tener cuando se produzca la llamada al procedimiento. Dentro del procedimiento, el parmetro formal se comporta como una variable sin inicializar, por lo que contiene el valor NULL. Puede leerse dicha variable y en escribirse en ella. Cuando el procedimiento finaliza y devuelve el control al entorno en el que se produjo la llamada, se asigna el valor del parmetro formal al parmetro real.

IN OUT - Este mtodo es una combinacin de los modos IN y OUT. El valor del parmetro real se pasa al procedimiento cuando se produce la llamada. Dentro del procedimiento, el parmetro formal se comporta como una variable inicializada, pudindose leer y escribir en ella. Cuando el procedimiento finaliza y devuelve el control al entorno en el que se produjo la llamada, los contenidos del parmetro formal se asignan al parmetro real.

-- Este procedimiento ilustra diferentes modos de parmetros y asignaciones de parmetros CREATE OR REPLACE PROCEDURE TEST ( p_In IN NUMBER, p_Out OUT NUMBER, p_InOut IN OUT NUMBER) IS v_LocalVariable NUMBER := 0; BEGIN DBMS_OUTPUT.PUT_LINE('AL PRINCIPIO DE Test:'); IF (p_In IS NULL) THEN DBMS_OUTPUT.PUT('p_In is NULL'); ELSE DBMS_OUTPUT.PUT('p_In = ' || p_In); END IF; IF (p_Out IS NULL) THEN DBMS_OUTPUT.PUT(' p_Out is NULL'); ELSE DBMS_OUTPUT.PUT(' p_Out = ' || p_Out); END IF; IF (p_InOut IS NULL) THEN DBMS_OUTPUT.PUT_LINE(' p_InOut is NULL'); ELSE DBMS_OUTPUT.PUT_LINE(' p_InOut = ' || p_InOut); END IF;

Resumen PL/SQL III

Pgina 7

/* Asignacin de p_In a v_LocalVariable. Esto est, permitido, ya que se lee de un parmetro con modo IN y no se escribe en el mismo. */ v_LocalVariable := p_In; -- Legal /* Asignacin de 7 a p_In. Esto NO EST PERMITIDO, ya que se estara escribiendo en un parmetro con modo IN. */ -- p_In := 7; -- Ilegal /* Asignacin de 7 a p_Out. Esto est permitido, ya que se est escribiendo en un parmetro con modo OUT. */ p_Out := 7; -- Legal /* Asignacin de p_Out a v_LocalVariable. En versiones anteriores a la 7.3, no est permitida la lectura de parmetros con modo OUT. */ v_LocalVariable := p_Out; -- Posiblemente ilegal /* Asignacin de p_InOutParameter a v_LocalVariable. Esto est permitido, ya que se lee de un parmetro con modo IN OUT. */ v_LocalVariable := p_InOut; -- Legal /* Asignacin de 8 a p_InOutParameter. Esto est permitido, ya que se escribe en un parmetro con modo IN OUT. */ p_InOut := 8; -- Legal DBMS_OUTPUT.PUT_LINE('AL FINAL DE Test:'); IF (p_In IS NULL) THEN DBMS_OUTPUT.PUT('p_In is NULL'); ELSE DBMS_OUTPUT.PUT('p_In = ' || p_In); END IF; IF (p_Out IS NULL) THEN DBMS_OUTPUT.PUT(' p_Out is NULL'); ELSE DBMS_OUTPUT.PUT(' p_Out = ' || p_Out); END IF; IF (p_InOut IS NULL) THEN DBMS_OUTPUT.PUT_LINE(' p_InOut is NULL'); ELSE DBMS_OUTPUT.PUT_LINE(' p_InOut = ' || p_InOut); END IF; END Test; / -- Este bloque llama a Test. DECLARE v_In NUMBER := 1; v_Out NUMBER := 2; v_InOut NUMBER := 3; BEGIN DBMS_OUTPUT.PUT_LINE('ANTES DE LLAMAR A TEST:'); DBMS_OUTPUT.PUT_LINE('v_In = ' || v_In ||' v_Out = ' || v_Out ||' v_InOut = ' || v_InOut); Test(v_In, v_Out, v_InOut); DBMS_OUTPUT.PUT_LINE('DESPUES DE LLAMAR A TEST:'); DBMS_OUTPUT.PUT_LINE(' v_In = ' || v_In ||' v_Out = ' || v_Out ||' v_InOut = ' || v_InOut); END; /

Resumen PL/SQL III

Pgina 8

Funcin FACTORIAL La siguiente funcin, calcula el valor factorial a partir de un nmero recibido.

CREATE OR REPLACE FUNCTION FACTORIAL(N IN NUMBER) RETURN NUMBER IS BEGIN IF N<0 THEN RETURN NULL; END IF; IF N=0 OR N=1 THEN RETURN 1; ELSE RETURN N*FACTORIAL(N-1); END IF; END;

SELECT FACTORIAL(4) FROM DUAL;

DECLARE V NUMBER :=5; BEGIN DBMS_OUTPUT.PUT_LINE(FACTORIAL(V )) ; END;

Funcin PRECIOMEDIO La siguiente funcin, calcula la media aritmtica del precio de venta de los artculos (PRECIO_VENTA_ART), a partir de los datos de la tabla de artculos(TARTICULO).

CREATE OR REPLACE FUNCTION PRECIOMEDIO RETURN NUMBER IS V_PRECIO NUMBER(11,4); BEGIN SELECT AVG(PRECIO_VENTA_ART) INTO V_PRECIO FROM TARTICULO; RETURN V_PRECIO; END; /

SELECT NOMBRE_ART, PRECIO_VENTA_ART, STOCK_ART FROM TARTICULO WHERE PRECIO_VENTA_ART > PRECIOMEDIO;

Resumen PL/SQL III

Pgina 9

LITERALES Y CONSTANTES COMO PARMETROS REALES

Debido al funcionamiento de los modos de parmetros, todo parmetro real que se corresponda con un parmetro OUT o IN OUT debe ser una variable, y no podr ser una constante o una expresin. Debe de existir una ubicacin para almacenar el valor que se devuelve.

CREATE OR REPLACE PROCEDURE TEST1 ( p_Out OUT NUMBER ) IS v_LocalVariable NUMBER := 5; BEGIN p_Out := v_LocalVariable; END; /

DECLARE var CONSTANT NUMBER(3,2):=0.16; BEGIN TEST1(var); END;

Resumen PL/SQL III

Pgina 10

RESTRICCIONES SOBRE LOS PARMETROS FORMALES


Cuando llamamos a un procedimiento, se pasan los valores de los parmetros reales y dentro del procedimiento, hacemos referencia a los mismos utilizando los parmetros formales. Las restricciones sobre las variables tambin se pasan como parte del mecanismo de paso de parmetros. En la declaracin de un procedimiento no podemos restringir la longitud de los parmetros de tipo CHAR o VARCHAR2, ni la precisin y/o escala de los de tipo NUMBER, debido a que las restricciones se tomarn de los parmetros reales.

-- Ejemplo de procedimiento errneo

CREATE OR REPLACE PROCEDURE Parametros ( p_Parameter1 IN OUT VARCHAR2(40), p_Parameter2 IN OUT NUMBER(3,1)) AS BEGIN p_Parameter1 := 'abcdefghijklm'; p_Parameter2 := 12.3; END Parametros;

Por otro lado, se puede generar un error al llamar al procedimiento, si el parmetro real tiene una restriccin de longitud menor, que los valores asignados al parmetro formal.

DECLARE v_Parameter1 VARCHAR2(5):= 'abc'; v_Parameter2 NUMBER(1) :=2; BEGIN parametros(v_Parameter1 , v_Parameter2 ); END ;

ERROR : buffer de cadenas de caracteres demasiado pequeo numrico o de valor ERROR : precisin de nmero demasiado grande numrico o de valor

Resumen PL/SQL III

Pgina 11

%TYPE Y PARMETROS DE PROCEDIMIENTO


Aunque no podamos declarar parmetros formales con restricciones, estas pueden imponerse utilizando %TYPE. Si declaramos un parmetro formal con %TYPE, y el tipo al que nos referimos est restringido, la restriccin actuar sobre el parmetro formal, y no sobre el parmetro real.

CREATE OR REPLACE PROCEDURE Parametros ( p_Parameter1 IN OUT VARCHAR2, p_Parameter2 IN OUT TARTICULO.CODIGO_CAT_ART%TYPE) AS BEGIN p_Parameter2 := 123; END Parametros;

Segn el ejemplo de PROCEDURE Parametros, p_Parameter2 tiene la restriccin de la columna TARTICULO.CODIGO_CAT_ART, que est de finida como NUMBER(3), por lo cual la siguiente llamada al procedimiento Parametros generar un error.

DECLARE v_Parameter1 VARCHAR2(5):= 'abc'; v_Parameter2 NUMBER(5) :=12345; BEGIN parametros(v_Parameter1 , v_Parameter2 ); END ;

ERROR : precisin de nmero demasiado grande numrico o de valor

Resumen PL/SQL III

Pgina 12

EXCEPCIONES GENERADAS EN UN SUBPROGRAMA


Si ocurre un error dentro de un subprograma, se genera una excepcin. Si el procedimiento no tiene control de excepcin, o bien, se genera la rutina de tratamiento de excepciones, se pasa inmediatamente el control al entorno que efectu la llamada, segn la propagacin de excepciones. Sin embargo, los valores de los parmetros formales con modo OUT y modo IN OUT no se devuelven a los parmetros reales.

CREATE OR REPLACE PROCEDURE RaiseError ( p_Raise IN BOOLEAN, p_ParameterA OUT NUMBER) AS BEGIN p_ParameterA := 7; IF p_Raise THEN RAISE DUP_VAL_ON_INDEX; END IF; END RaiseError;

DECLARE v_TempVar NUMBER := 1; BEGIN DBMS_OUTPUT.PUT_LINE('Valor inicial: ' || v_TempVar); RaiseError(FALSE, v_TempVar); DBMS_OUTPUT.PUT_LINE('Valor despus de la 1 llamada: ' || v_TempVar); v_TempVar := 2; DBMS_OUTPUT.PUT_LINE('Valor antes de la 2 llamada: ' || v_TempVar); RaiseError(TRUE, v_TempVar); EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Valor despus de la 2 llamada: ' || v_TempVar); END;

Resumen PL/SQL III

Pgina 13

PASO DE PARMETROS POR REFERENCIA Y POR VALOR


Los parmetros de los subprogramas pueden pasarse por referencia o por valor. Cuando se pasa un parmetro por referencia, lo que se pasa al parmetro formal correspondiente es un puntero al parmetro real. Cuando se pasa un parmetro por valor, se copia el valor del parmetro real al parmetro formal. El paso de parmetro por referencia es generalmente ms rpido, ya que ahorra la realizacin de la copia, especialmente en el caso de parmetros de colecciones (tablas, varrays). De forma predeterminada, PL/SQL pasa los parmetros de modo IN por referencia y los parmetros de modo IN OUT y OUT por valor, para mantener la semntica de excepciones y para que las restricciones sobre parmetros reales puedan verificarse.

UTILIZACIN DE NOCOPY
A partir de Oracle 8i se incluye la indicacin de compilacin NOCOPY, la sintaxis para utilizar dicha indicacin a la hora de declarar un parmetro es la siguiente

<NOMBRE_PARMETRO> <MODO> NOCOPY <TIPO_DATO>

Si NOCOPY est especificado, el compilador PL/SQL intenta pasar el parmetro por referencia, en lugar de por valor.

CREATE OR REPLACE PROCEDURE NoCopyTest ( p_InParametro IN NUMBER, p_OutParametro OUT NOCOPY VARCHAR2, p_InOutParametro IN OUT NOCOPY CHAR) IS BEGIN NULL; END NoCopyTest;

La utilizacin de NOCOPY con un parmetro de modo IN da error de compilacin. Cuando pasamos un parmetro por referencia, cualquier modificacin del parmetro formal tambin modifica el parmetro real, ya que ambos apuntan al mismo lugar. Esto significa que, si se produce una excepcin despus de haber modificado el parmetro formal, el valor original del parmetro real se habr perdido.

Resumen PL/SQL III

Pgina 14

CREATE OR REPLACE PROCEDURE RaiseError ( p_Raise IN BOOLEAN, p_ParameterA OUT NOCOPY NUMBER) AS BEGIN p_ParameterA := 7; IF p_Raise THEN RAISE DUP_VAL_ON_INDEX; ELSE RETURN; END IF; END RaiseError; /

DECLARE v_TempVar NUMBER := 1; BEGIN DBMS_OUTPUT.PUT_LINE('Valor inicial: ' || v_TempVar); RaiseError(FALSE, v_TempVar); DBMS_OUTPUT.PUT_LINE('Valor despus de la 1 llamada: ' || v_TempVar); v_TempVar := 2; DBMS_OUTPUT.PUT_LINE('Valor antes de la 2 llamada: ' || v_TempVar); RaiseError(TRUE, v_TempVar); EXCEPTION WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Valor despus de la 2 llamada: ' || v_TempVar); END;

Resumen PL/SQL III

Pgina 15

NOTACIN POSICIONAL Y NOTACIN NOMINAL


Los parmetros formales se encuentran asociados a los parmetros reales por su posicin. Alternativamente puede realizarse una llamada a un procedimiento utilizando la notacin nominal, en la cual, para cada argumento, se incluye tanto el parmetro formal, como el parmetro real, lo que nos permite modificar el orden de los argumentos. Las notaciones nominal y posicional pueden utilizarse conjuntamente en la misma llamada, en tal caso, los primeros argumentos a especificar deben ser por posicin.

CREATE OR REPLACE PROCEDURE nominal( p_ParametroA VARCHAR2, p_ParametroB NUMBER, p_ParametroC BOOLEAN, p_ParametroD DATE) AS BEGIN NULL; END nominal;

DECLARE v_Variable1 VARCHAR2(10); v_Variable2 NUMBER(7,6); v_Variable3 BOOLEAN; v_Variable4 DATE; BEGIN nominal(p_ParametroA => v_Variable1, p_ParametroB => v_Variable2, p_ParametroC => v_Variable3, p_ParametroD => v_Variable4); END;

Las notaciones nominal y posicional pueden utilizarse conjuntamente en la misma llamada, en tal caso, los primeros argumentos a especificar deben ser por posicin.

DECLARE v_Variable1 VARCHAR2(10); v_Variable2 NUMBER(7,6); v_Variable3 BOOLEAN; v_Variable4 DATE; BEGIN nominal(v_Variable1, v_Variable2, p_ParametroC => v_Variable3, p_ParametroD => v_Variable4); END;

Resumen PL/SQL III

Pgina 16

VALOR PREDETERMINADO DE LOS PARAMETROS

Al igual que las declaraciones de las variables, los parmetros formales pueden tener valores predeterminados. Si un determinado parmetro tiene un valor por defecto, no es obligatorio pasarlo desde la llamada. Si se pasa valor, el valor del parmetro real sustituir al predeterminado. La sintaxis a utilizar:

<NOMBRE_PARMETRO> <MODO> <NOMBRE_PARMETRO> <MODO>

<TIPO_DATO> := <VALOR_INICIAL> <TIPO_DATO> DEFAULT <VALOR_INICIAL>

CREATE OR REPLACE PROCEDURE DefaultTest ( p_ParametroA NUMBER DEFAULT 10, p_ParametroB VARCHAR2 DEFAULT 'abcdef', p_ParametroC DATE DEFAULT SYSDATE) AS BEGIN DBMS_OUTPUT.PUT_LINE('A: '|| p_ParametroA ||' B: ' || p_ParametroB ||' C:' || TO_CHAR(p_ParametroC,'DD-MM-YYYY')); END DefaultTest;

BEGIN DefaultTest(p_ParametroA => 7, p_ParametroC => '01-FEB-08'); END;

BEGIN -- Usa el valor predeterminado tanto para p_ParametroB -- como para p_ParametroC. DefaultTest(20); END;

Resumen PL/SQL III

Pgina 17

PAQUETES
Un paquete es una estructura de PL/SQL que permite almacenar juntos varios objetos relacionados entre s. Un paquete tiene dos partes separadas: la especificacin y el cuerpo. Cada una de ellas se almacena independientemente en el diccionario de datos. Un paquete es fundamentalmente una seccin declarativa. Cualquier cdigo que pueda incluirse en la parte declarativa de un bloque puede incluirse en un paquete, incluidos procedimientos, funciones, cursores y variables. Los paquetes no pueden ser llamados o pasados como parmetros. La especificacin del paquete incluye informacin acerca del contenido del paquete. Sin embargo no contiene cdigo para ninguno de los procedimientos.

CREATE [ OR REPLACE ] PACKAGE <NOMBRE_PAQUETE> IS -- Especificaciones de procedimientos -- Especificaciones de funciones -- Declaraciones de variables -- Declaraciones de excepciones -- Declaraciones de cursores END [<NOMBRE_PAQUETE>];

El cuerpo del paquete es un objeto independiente de la cabecera del paquete en el diccionario de datos. El cuerpo del paquete no puede compilarse hasta que la cabecera del paquete se haya compilado correctamente. El cuerpo contiene el cdigo correspondiente a las declaraciones formales de los subprogramas que aparecen en la cabecera del paquete.

CREATE [ OR REPLACE ] PACKAGE BODY <NOMBRE_PAQUETE> IS -- Declaraciones de los subprogramas END [<NOMBRE_PAQUETE>];

Cualquier objeto que se declare en la cabecera del paquete, se encuentra dentro de mbito y es visible desde fuera del paquete, siempre que el objeto se distinga precedindole con el nombre del paquete donde se encuentra definido.

Resumen PL/SQL III

Pgina 18

SOBRECARGA DE SUBPROGRAMAS EMPAQUETADOS


Los procedimientos y funciones dentro de un paquete pueden sobrecargarse, lo que significa que puede haber ms de un procedimiento o una funcin con el mismo nombre, pero con diferentes parmetros. La sobrecarga est permitida para distinto nmero de parmetros, o bien, para distinto tipo de familia de dato. No est permitida para diferentes tipos retornados por una funcin, ni para distintos modos de recepcin de los parmetros (IN, OUT, IN OUT).

INICIALIZACIN DEL PAQUETE


El paquete se instancia la primera vez que se llama a uno de los subprogramas en l empaquetados, lo que significa que el paquete se lee de disco y se lleva a memoria, y se ejecuta el cdigo compilado del subprograma al que se llama. En esta situacin se asigna memoria para todas las variables definidas en el paquete. Cada sesin tendr su propia copia de las variables empaquetadas, asegurando que dos sesiones que ejecuten subprogramas contenidos en el mismo paquete utilicen ubicaciones de memoria diferentes. En ocasiones, es conveniente ejecutar un cdigo de inicializacin la primera vez que se instancia el paquete, lo que puede hacerse aadiendo una seccin de inicializacin en el cuerpo del paquete, despus de todos los dems objetos. CREATE [ OR REPLACE ] PACKAGE BODY <NOMBRE_PAQUETE> IS BEGIN -- Cdigo de Inicializacin END [<NOMBRE_PAQUETE>];

Resumen PL/SQL III

Pgina 19

ESPECIFICACIN DEL PAQUETE OPERAR


CREATE OR REPLACE PACKAGE OPERAR IS FUNCTION SUMAR(N1 IN NUMBER, N2 IN NUMBER) RETURN NUMBER; FUNCTION SUMAR(N1 IN VARCHAR2, N2 IN VARCHAR2) RETURN VARCHAR2; FUNCTION RESTAR(N1 IN NUMBER, N2 IN NUMBER) RETURN NUMBER; FUNCTION DIVIDIR(N1 IN NUMBER, N2 IN NUMBER) RETURN NUMBER; FUNCTION MULTIPLICAR(N1 IN NUMBER, N2 IN NUMBER) RETURN NUMBER; RESULTADO NUMBER; END OPERAR;

CUERPO DEL PAQUETE OPERAR


CREATE OR REPLACE PACKAGE BODY OPERAR IS FUNCTION SUMAR(N1 IN NUMBER,N2 IN NUMBER) RETURN NUMBER IS BEGIN RESULTADO:=N1+N2; RETURN RESULTADO; END SUMAR; FUNCTION RESTAR(N1 IN NUMBER, N2 IN NUMBER) RETURN NUMBER IS BEGIN RETURN N1-N2; END RESTAR; FUNCTION MULTIPLICAR(N1 IN NUMBER, N2 IN NUMBER) RETURN NUMBER IS BEGIN RETURN N1*N2; END MULTIPLICAR; FUNCTION DIVIDIR(N1 IN NUMBER, N2 IN NUMBER) RETURN NUMBER IS BEGIN RETURN N1/N2; END DIVIDIR; FUNCTION SUMAR(N1 IN VARCHAR2, N2 IN VARCHAR2) RETURN VARCHAR2 IS BEGIN RETURN CONCAT(N1,N2); END SUMAR; END OPERAR;

EJECUCIN DEL PAQUETE OPERAR


SELECT OPERAR.DIVIDIR (12, 3) FROM DUAL; SELECT OPERAR.SUMAR (12, 3) FROM DUAL; SELECT OPERAR.SUMAR ('BUENAS ', 'TARDES') FROM DUAL;

Resumen PL/SQL III

Pgina 20

TRIGGER
TIPOS DE DISPARADORES
Los disparadores son parecidos a los procedimientos y funciones, en el sentido de que son bloques de PL/SQL con secciones declarativa, ejecutable y de tratamiento de excepciones. Los disparadores deben almacenarse en la base de datos como objetos independientes y no pueden ser locales a un bloque o paquete. Un TRIGGER difiere en gran medida de un procedimiento almacenado en la B.D. ya que unos son ejecutados de manera explcita por el usuario, una aplicacin o un TRIGGER y los otros son ejecutados de manera implcita por Oracle ante la ocurrencia de algn evento. El suceso que lo activa puede ser una operacin DML (INSERT, UPDATE o DELETE) sobre una tabla e incluso en algunas ocasiones sobre una vista. Existen tres tipos de disparadores: DML, de sustitucin y del sistema. Los disparadores son ampliamente empleados en la personalizacin de la Administracin de la B.D. por ejemplo: un TRIGGER puede restringir las operaciones DML sobre una tabla en particular en ciertas horas del da, durante una o varias semanas o incluso meses. Otras aplicaciones de los TRIGGERS pueden ser las siguientes: generacin automtica de valores derivados de una columna, prevenir transacciones invlidas, proporcionar auditorias sofisticadas, generar estadsticas de acceso, publicar informacin de los eventos generados por la B.D., las actividades de los usuarios o de las estructuras SQL que se ha ejecutado.

CREACIN DE DISPARADORES
CREATE [OR REPLACE] TRIGGER <NOMBRE_DISPARADOR> BEFORE | AFTER | INSTEAD OF DELETE | INSERT | UPDATE [OF <NOMBRE_COLUMNA> ] ON <NOMBRE_TABLA> [ FOR EACH ROW ] [ WHEN <CONDICIN> ] { <BLOQUE PL/SQL> }

END [<NOMBRE_DISPARADOR>] ;

Resumen PL/SQL III

Pgina 21

DISPARADORES DML

Los disparadores DML se activan a partir de instrucciones DML y el tipo de instruccin determina el tipo de disparador. Estos pueden definirse para las instrucciones INSERT, DELETE y/o UPDATE y podrn dispararse antes o despus de la operacin. Dichos disparadores pueden dispararse en operaciones de fila o de instruccin. Las combinaciones de estos factores determinan el tipo de disparador (un total de 12). Un disparador puede tambin dispararse para ms de un tipo de instruccin DML sobre una tabla. El cdigo de disparador se ejecutar junto con la propia instruccin de disparo, como parte de la misma transaccin. Una tabla puede tener cualquier nmero de disparadores definido sobre la misma, incluyendo ms de un disparador DML del mismo tipo. Por ejemplo, pueden definirse dos disparadores posteriores a la insercin y de nivel de fila. Todos los disparadores del mismo tipo se activarn de forma secuencial. Por defecto el disparador se ejecuta por instruccin, si se desea que se ejecute por cada fila que afecte la instruccin, tenemos que especificar la clusula FOR EACH ROW. Si deseamos que el disparador se lance cuando afecte a una determinada columna, debemos indicarlo mediante la sintaxis OF <NOMBRE_COLUMNA_1> [ , <NOMBRE_COLUMNA_2>...]

Ejemplos: CREATE TRIGGER CAMBIO_CATEGORIA BEFORE DELETE OR INSERT OR UPDATE ON TCATEGORIA <BLOQUE PL/SQL> . . .. .. END CAMBIO_CATEGORIA;

Resumen PL/SQL III

Pgina 22

CREATE TRIGGER CHEQUEAR_ART BEFORE INSERT OR UPDATE OF PRECIO_VENTA_ART, PESO_ART ON TARTICULO FOR EACH ROW WHEN (:NEW.CODIGO_CAT_ART = '101') <BLOQUE PL/SQL> . . .. .. END CHEQUEAR_ART;

CREATE TRIGGER CHEQUEAR_ART BEFORE INSERT OR UPDATE OF PRECIO_VENTA_ART, PESO_ART ON TARTICULO FOR EACH ROW WHEN (NEW.CODIGO_CAT_ART = '101') PROCEDIMIENTO_ART (:NEW.CODIGO_ART, :NEW.PESO_ART); END CHEQUEAR_ART;

Resumen PL/SQL III

Pgina 23

ORDEN DE ACTIVACIN DE LOS DISPARADORES

1 Ejecucin de los disparadores previos de nivel de instruccin. 2 Para cada fila aceptada por la instruccin: 2.A Ejecucin de los disparadores previos de nivel de fila. 2.B Ejecucin de la propia instruccin. 2.C Ejecucin de los disparadores posteriores de nivel de fila. 3 Ejecucin de los disparadores posteriores de nivel de instruccin.

EJEMPLO ORDEN DE ACTIVACIN


Secuencia
CREATE SEQUENCE trig_seq START WITH 1 INCREMENT BY 1 NOCACHE;

Tabla
CREATE TABLE temp_table ( num_col NUMBER(3), char_col VARCHAR2(50) ) ;

Resumen PL/SQL III

Pgina 24

Paquete
CREATE OR REPLACE PACKAGE TrigPackage AS -- Contador global que se usa en los disparadores v_Contador NUMBER; END TrigPackage;

Disparadores
CREATE OR REPLACE TRIGGER BINSTRUCCION BEFORE UPDATE ON TProveedores BEGIN -- Puesta a cero del contador. TrigPackage.v_Contador := 0; INSERT INTO temp_table (num_col, char_col) VALUES (trig_seq.NEXTVAL,'Before INSTRUCCION: Contador = ' || TrigPackage.v_Contador); -- Incremento del contador para el prximo disparador. TrigPackage.v_Contador := TrigPackage.v_Contador + 1; END BINSTRUCCION; /

CREATE OR REPLACE TRIGGER AINSTRUCCION1 AFTER UPDATE ON TProveedores BEGIN INSERT INTO temp_table (num_col, char_col) VALUES (trig_seq.NEXTVAL,'After INSTRUCCION 1: Contador = ' || TrigPackage.v_Contador); -- Incremento del contador para el prximo disparador. TrigPackage.v_Contador := TrigPackage.v_Contador + 1; END AINSTRUCCION1; /

CREATE OR REPLACE TRIGGER AINSTRUCCION2 AFTER UPDATE ON TProveedores BEGIN INSERT INTO temp_table (num_col, char_col) VALUES (trig_seq.NEXTVAL, 'After INSTRUCCION 2: Contador = ' ||TrigPackage.v_Contador); -- Incremento del contador para el prximo disparador. TrigPackage.v_Contador := TrigPackage.v_Contador + 1; END AINSTRUCCION2; /

CREATE OR REPLACE TRIGGER BFILA1 BEFORE UPDATE ON TProveedores FOR EACH ROW BEGIN INSERT INTO temp_table (num_col, char_col) VALUES (trig_seq.NEXTVAL, 'Before FILA 1: Contador = ' || TrigPackage.v_Contador); -- Incremento del contador para el prximo disparador. TrigPackage.v_Contador := TrigPackage.v_Contador + 1; END BFILA1; /

Resumen PL/SQL III

Pgina 25

Disparadores

(Cont.)

CREATE OR REPLACE TRIGGER BFILA2 BEFORE UPDATE ON TProveedores FOR EACH ROW BEGIN INSERT INTO temp_table (num_col, char_col) VALUES (trig_seq.NEXTVAL, 'Before FILA 2: Contador = ' || TrigPackage.v_Contador); -- Incremento del contador para el prximo disparador. TrigPackage.v_Contador := TrigPackage.v_Contador + 1; END BFILA2; /

CREATE OR REPLACE TRIGGER BFILA3 BEFORE UPDATE ON TProveedores FOR EACH ROW BEGIN INSERT INTO temp_table (num_col, char_col) VALUES (trig_seq.NEXTVAL, 'Before FILA 3: Contador = ' || TrigPackage.v_Contador); -- Incremento del contador para el prximo disparador. TrigPackage.v_Contador := TrigPackage.v_Contador + 1; END BFILA3; /

CREATE OR REPLACE TRIGGER AFILA AFTER UPDATE ON TProveedores FOR EACH ROW BEGIN INSERT INTO temp_table (num_col, char_col) VALUES (trig_seq.NEXTVAL, 'After FILA: Contador = ' || TrigPackage.v_Contador); -- Incremento del contador para el prximo disparador. TrigPackage.v_Contador := TrigPackage.v_Contador + 1; END AFILA; /

Resumen PL/SQL III

Pgina 26

Sentencia activadora Y resultado

UPDATE TProveedores SET poblacion_pr = 'LEGANS' WHERE cod_pr IN ('PCC', 'ASU'); SELECT * FROM temp_table ORDER BY num_col;

Resumen PL/SQL III

Pgina 27

EJEMPLO INICIALIZACION DE UN CODIGO SECUENCIALMENTE


Completa el campo CODIGO_CAT de la tabla de categoras con el prximo valor que genere la secuencia CODIGO_CAT. Como CODIGO_CAT es una columna la tabla de categoras, :new.CODIGO_CAT es una referencia vlida. Secuencia

Tabla
SELECT * FROM TCATEGORIA ORDER BY CODIGO_CAT ;

Disparador
CREATE OR REPLACE TRIGGER COD_CAT_NUEVO BEFORE INSERT ON TCATEGORIA FOR EACH ROW BEGIN SELECT CODIGO_CAT.NEXTVAL INTO :NEW.CODIGO_CAT END COD_CAT_NUEVO;

FROM DUAL;

Resumen PL/SQL III

Pgina 28

Sentencia activadora
INSERT INTO TCATEGORIA (NOMBRE_CAT ) VALUES ('IMPRESORAS');

Resultado
SELECT * FROM TCATEGORIA ORDER BY CODIGO_CAT ;

IDENTIFICADORES DE CORRELACIN EN DISPARADORES DE NIVEL DE FILA

Un disparador de nivel de fila se activa una vez por cada fila que procese la instruccin de disparo. Dentro del disparador, es posible acceder a los datos de la fila que se est procesando. Esto es posible mediante dos identificadores de correlacin :new y :old. El carcter dos puntos que les precede, indica que son variables de acoplamiento. La sintaxis :new.nombre_campo, es vlida nicamente si nombre_campo es un campo de la tabla disparo. El identificador :old tendr los valores originales antes del borrado, o de la modificacin y NULL para el proceso de insercin. El identificador :new tendr los valores nuevos de la modificacin, o de la insercin y NULL para el proceso de borrado.

Resumen PL/SQL III

Pgina 29

CLUSULA REFERENCING

Si deseamos dar un nombre diferente para los identificadores de correlacin :new y :old, podemos utilizar la clusula referencing. Dicha clusula se incluye despus del suceso de disparo y antes de la clusula when y for each row .

REFERENCING [ OLD AS <nombre_old> ] [ NEW AS <nombre_new> ]

En el cuerpo del disparador se podr utilizar :nombre_old y :nombre_new en lugar de :old y :new. En la clusula referencing los identificadores se escriben sin los dos puntos.

EJEMPLO INICIALIZACION DE UN CODIGO CLUSULA REFERENCING


Disparador
CREATE OR REPLACE TRIGGER COD_CAT_NUEVO BEFORE INSERT ON TCATEGORIA REFERENCING NEW AS CATEGORIA_NUEVA FOR EACH ROW BEGIN SELECT CODIGO_CAT.NEXTVAL INTO :CATEGORIA_NUEVA.CODIGO_CAT FROM DUAL; END COD_CAT_NUEVO;

Sentencia activadora
INSERT INTO TCATEGORIA (NOMBRE_CAT ) VALUES ('FOTOGRAFA');

Resultado
SELECT * FROM TCATEGORIA ORDER BY CODIGO_CAT ;

Resumen PL/SQL III

Pgina 30

CLUSULA WHEN
La clusula WHEN es nicamente valida en los disparadores de nivel de fila. El cuerpo del disparador, solo se ejecutar sobre aquellas filas que cumplan la condicin especificada.

WHEN <condicin_disparador>

PREDICADOS DE DISPARADORES
Para un disparador que se pueda activar por diferentes acciones producidas ( INSERT, DELETE, UPDATE) , existen tres funciones booleanas que se pueden utilizar para determinar qu operacin ha lanzado el disparador.

INSERTING Verdadero si la instruccin de disparo es INSERT, falso en cualquier otro caso.

UPDATING Verdadero si la instruccin de disparo es UPDATE.

DELETING Verdadero si la instruccin de disparo es DELETE.

BEGIN IF INSERTING THEN <proceso_insertar>; ELSIF UPDATING THEN <proceso_modificar>; ELSE <proceso_borrar>; END IF;

Resumen PL/SQL III

Pgina 31

DISPARADORES DE SUSTITUCIN
A diferencia de los disparadores DML, que actan adems de las operaciones INSERT, UPDATE y DELETE, los disparadores de sustitucin actan en lugar de la orden DML. Los disparadores de sustitucin pueden definirse nicamente sobre vistas, mientras que los disparadores DML se definen sobre tablas.

Existe una clasificacin entre vistas modificables y vistas no modificables. Una vista modificable es aquella que permite una instruccin DML. En general, una vista es modificable si no contiene uniones (INNER JOIN, campos de ms de una tabla), agregaciones (SUM, COUNT), agrupaciones (GROUP BY) ni el operador DISTINCT. Sin embargo algunas vistas que trabajan con ms de una tabla, puede ser modificable si la operacin DML ejecutada solo afecta a columnas de una sola tabla base.

Si una vista no es modificable, es posible escribir un disparador de sustitucin que realice las operaciones deseadas, permitiendo as la modificacin de la misma. Los disparadores de sustitucin, por supuesto, tambin pueden escribirse para vistas modificables.

La clusula FOR EACH ROW es opcional para los disparadores de sustitucin, ya que todos los disparadores de sustitucin son de nivel de fila, independientemente de poner la clusula o no.

Resumen PL/SQL III

Pgina 32

EJEMPLO DISPARADOR DE SUSTITUCIN


Al insertar registros sobre una vista, compuesta por columnas de las tablas proveedores y pedidos, se ejecutar ste disparador de sustitucin, que se encarga de crear un nuevo registro en la tabla proveedores y otro nuevo registro en la tabla pedidos. Vista
CREATE OR REPLACE VIEW PEDIDOS_COMPRA_PROVEEDOR AS SELECT cif_PC cif, cod_pr cod, nombre_pr nombre, comercial_pc comercial, forma_pago_pc fp FROM tproveedores INNER JOIN tpedidos_compra ON cif_pr = cif_pc; persona_pr persona,

Disparador
CREATE OR REPLACE TRIGGER insert_pedido_prov instead OF INSERT ON PEDIDOS_COMPRA_PROVEEDOR DECLARE v_pr VARCHAR2(15); CURSOR c_prov IS SELECT cif_pr FROM tproveedores WHERE cif_pr = :NEW.cif; FUNCTION buscar_pr RETURN boolean IS v_encontrado boolean := TRUE; BEGIN OPEN c_prov; FETCH c_prov INTO v_pr; v_encontrado := c_proV % FOUND; CLOSE c_proV; RETURN v_encontrado; END buscar_pr; BEGIN IF NOT BUSCAR_PR() THEN INSERT INTO tproveedores(cif_pr, nombre_pr, cod_pr) VALUES(:NEW.cif, :NEW.nombre, :NEW.cod); END IF; INSERT INTO tpedidos_compra(numero_pedido_pc, cif_pc, comercial_pc, forma_pago_pc) VALUES('PC-' || TRIM (' ' FROM TO_CHAR (NUMERO_PEDIDO_PC.NEXTVAL , '000000') ), :NEW.cif, :NEW.comercial, :NEW.fp); END insert_pedido_prov;

Resumen PL/SQL III

Pgina 33

Sentencia activadora
INSERT INTO PEDIDOS_COMPRA_PROVEEDOR (CIF,COD, NOMBRE, PERSONA, COMERCIAL, FP) VALUES ('A-33317884', 'PIO', 'PIONNER', 'JOSE MARIA', 'MARCOS SERRANO', '90');

Resultado
select NUMERO_PEDIDO_PC, CIF_PC, FECHA_PEDIDO_PC, FECHA_ENTRADA_PC, FORMA_PAGO_PC, COMERCIAL_PC, PORTES_PC, OBSERVACIONES_PC from TPEDIDOS_COMPRA;

select CIF_PR, COD_PR, NOMBRE_PR, DIR_PR, POBLACION_PR, PROVINCIA_PR, PAIS_PR, CP_PR,TLF1_PR, FAX_PR, PERSONA_PR from TPROVEEDORES;

Resumen PL/SQL III

Pgina 34

TRIGGERS DEL SISTEMA


Tanto los disparadores DML como los de sustitucin se disparan junto con, o en lugar de los sucesos DML, es decir las instrucciones INSERT, UPDATE o DELETE. Los disparadores del sistema por el contrario, se disparan a consecuencia de dos tipos de sucesos distintos los DDL, o los de base de datos. Los sucesos DDL incluyen las instrucciones CREATE, ALTER o DROP, mientras que los sucesos de base de datos incluyen la conexin y desconexin del servidor, el inicio y finalizacin de la sesin de usuario y los errores del servidor.

CREATE [OR REPLACE] TRIGGER <NOMBRE_DISPARADOR> BEFORE | AFTER <Lista_sucesos_DDL> |<Lista_sucesos_base_datos> ON DATABASE | [<esquema>.]SCHEMA [ WHEN <clusula> ] { PL/SQL Bloque } . . END [<NOMBRE_DISPARADOR> ] ;

Un disparador del sistema puede definirse en el nivel de base de datos o en el nivel de esquema. Un disparador de nivel de base de datos se activar siempre que ocurra el suceso de disparo, mientras que un disparador de nivel de esquema se activara nicamente cuando ocurra el suceso de disparo en el esquema especificado. Las palabras clave DATABASE y SCHEMA determinan el nivel de un disparador del sistema dado. Si el esquema no se especifica mediante la palabra clave SCHEMA, el valor predeterminado es el esquema propietario del disparador.

Resumen PL/SQL III

Pgina 35

SUCESOS

STARTUP AFTER

Se dispara cuando se inicia una instancia.

SHUTDOWN BEFORE

Se dispara cuando se cierra una instancia.

SERVERERROR AFTER

Se dispara cuando se produce un error.

LOGON AFTER

Se dispara despus de que un usuario se haya conectado a la base de datos.

LOGOFF BEFORE

Se dispara al inicio de la finalizacin de una sesin de usuario.

CREATE BEFORE | AFTER

Se dispara antes o despus de la creacin de un objeto en la base de datos.

DROP BEFORE | AFTER

Se dispara antes o despus de la eliminacin de un objeto en la base de datos.

ALTER BEFORE | AFTER

Se dispara antes o despus de la modificacin de un objeto en la base de datos.

Resumen PL/SQL III

Pgina 36

EJEMPLO DISPARADOR DE SISTEMA Creado como SYSTEM


Tabla
CREATE TABLE temp_table ( num_col NUMBER(3), char_col VARCHAR2(50) ) ;

Disparador.
CREATE OR REPLACE TRIGGER TRABAJA_APLICACION AFTER DROP OR CREATE OR ALTER ON A01.SCHEMA BEGIN INSERT INTO temp_table VALUES (8, CONCAT('TRABAJA: ' , USER) ); END TRABAJA_APLICACION;

Sentencia activadora. Ejecutado como A01


CREATE SEQUENCE SECUENCIA_EJEMPLO START WITH 10000 INCREMENT BY 1;

Sentencia activadora. Ejecutado como A01


DROP SEQUENCE SECUENCIA_EJEMPLO;

Resultado
SELECT * FROM TEMP_TABLE;

Resumen PL/SQL III

Pgina 37

Disparador.

CREATE OR REPLACE TRIGGER CONECTA_TODOS AFTER LOGON ON DATABASE BEGIN INSERT INTO temp_table VALUES (2,CONCAT( 'CONECTADOS USUARIO ' , USER) ); END CONECTA_TODOS;

Disparador

CREATE OR REPLACE TRIGGER CONECTA_APLICACION AFTER LOGON ON A01.SCHEMA BEGIN INSERT INTO temp_table VALUES (1, CONCAT('CONECTA USUARIO ' , USER) ); END CONECTA_APLICACION;

Resultado
SELECT NUM_COL,CHAR_COL FROM TEMP_TABLE ORDER BY NUM_COL ;

Resumen PL/SQL III

Pgina 38

FUNCIONES DE ATRIBUTOS DE SUCESOS

Dentro de los disparadores del sistema hay varias funciones de atributos de sucesos disponibles. Estas permiten que el cuerpo de un disparador obtenga informacin sobre el suceso de disparo. Las funciones de atributos de sucesos son funciones PL/SQL independientes que pertenecen a SYS. Por omisin, no existen sinnimos definidos para las mismas, por lo que deben ir precedidas de SYS para que puedan resolverse.

Algunas funciones de atributos de sucesos: DICTIONARY_OBJ_TYPE Devuelve un VARCHAR2(20), aplicable a los sucesos CREATE, DROP, ALTER. Devuelve el tipo de objeto de diccionario sobre el que tuvo lugar la operacin DDL que activ el suceso.

DICTIONARY_OBJ_NAME Devuelve un VARCHAR2(30), aplicable a los sucesos CREATE, DROP, ALTER. Devuelve el nombre del objeto de diccionario sobre el que tuvo lugar la operacin DDL que activ el suceso.

DICTIONARY_OBJ_OWNER Devuelve un VARCHAR2(30), aplicable a los sucesos CREATE, DROP, ALTER. Devuelve el propietario del objeto de diccionario sobre el que tuvo lugar la operacin DDL que activ el suceso.

SYSEVENT Devuelve un VARCHAR2(20), aplicable a todos los sucesos. Devuelve el suceso del sistema que activ el disparador.

LOGIN_USER Devuelve un VARCHAR2(30), aplicable a todos los sucesos. Devuelve el identificador del usuario que activ el disparador.

Resumen PL/SQL III

Pgina 39

EJEMPLO DISPARADOR DE SISTEMA Creado como SYSTEM


Tabla.

CREATE TABLE NUEVOS_OBJETOS ( USUARIO VARCHAR2(30), OBJETO VARCHAR2(20), NOMBRE VARCHAR2(30), PROPIETARIO VARCHAR2(30), FECHA DATE);

Disparador.
CREATE OR REPLACE TRIGGER T_NUEVOS_OBJETOS AFTER CREATE ON DATABASE BEGIN INSERT INTO NUEVOS_OBJETOS (USUARIO, OBJETO, NOMBRE, PROPIETARIO, FECHA) VALUES (USER, SYS.DICTIONARY_OBJ_TYPE , SYS.DICTIONARY_OBJ_NAME, SYS.DICTIONARY_OBJ_OWNER , SYSDATE); END T_NUEVOS_OBJETOS;

Sentencia activadora. Ejecutado como A01


CREATE SEQUENCE SECUENCIA_EJEMPLO START WITH 10000 INCREMENT BY 1; DROP SEQUENCE SECUENCIA_EJEMPLO;

Sentencia activadora. Ejecutado como SYSTEM


CREATE SEQUENCE SECUENCIA_EJEMPLO START WITH 10000 INCREMENT BY 1; DROP SEQUENCE SECUENCIA_EJEMPLO; CREATE SEQUENCE EJEMPLO2 START WITH 10000 INCREMENT BY 1; DROP SEQUENCE EJEMPLO2;

Resultado
SELECT * FROM NUEVOS_OBJETOS ;

Resumen PL/SQL III

Pgina 40

TABLA MUTANTE
Una tabla mutante es una tabla que se est modificando debido a una instruccin DML. En el caso de un disparador es la tabla a la que se refiere el disparador en la clusula ON. Un disparador no puede leer o modificar una tabla mutante ni tampoco leer o modificar una columna de clave externa relativa a una restriccin de la tabla a la que se refiere el trigger (s se podra utilizar y modificar el resto de columnas). Es decir, no podemos hacer consultas ni instrucciones DML sobre una tabla sobre la que ya se ha comenzado a modificar, insertar o eliminar datos. En realidad slo los triggers de fila no pueden acceder a tablas mutantes. Por ello la solucin al problema suele ser combinar triggers de tabla con triggers de fila (conociendo el orden de ejecucin de los triggers). Normalmente los triggers de fila almacenan los valores que se desean cambiar dentro de una tabla preparada al efecto o dentro de variables de paquete (accesibles desde cualquier trigger si se crea dentro de dicho paquete).

Resumen PL/SQL III

Pgina 41

Вам также может понравиться