Anda di halaman 1dari 5

Restricciones y Triggers

Las restricciones son declaraciones de condiciones sobre la base de datos que debe permanecer verdaderas. stas incluyen restricciones basado en atributos, en tuplas, en llaves, y restricciones de integridad de referencial. El sistema inspecciona la violacin de las restricciones sobre acciones que pueden causar una violacin, y aborta la accin de acuerdo con lo especificado en la restriccin. La informacin sobre las restricciones del SQL puede encontrarse en el libro de texto. La implementacin de restricciones en Oracle difiere del standard SQL, ver documento [1] Los disparadores (o triggers) son una estructura especial del PL/SQL similar a los procedimientos. Sin embargo, un procedimiento se ejecuta explcitamente desde otro bloque va un procedimiento de llamado, mientras un disparador se ejecuta implcitamente siempre que el evento activando ocurra. El evento que activa el disparador es una orden de INSERCIN (INSERT), de BORRADO (DELETE), o de ACTUALIZACION (UPDATE). La eleccin del momento adecuado o puede ser ANTES o DESPUS DE (BEFORE o AFTER). El trigger puede estar definido a nivel de fila o de instruccin, donde los primeros realizan la accin una vez para cada fila afectada en el evento y los segundos realizan la accin una vez por toda la instruccin.

Restricciones: Difiriendo la comprobacin de una restriccin Violacin de una Restriccin Triggers: Sintaxis Bsica de un Trigger Ejemplo de Trigger Desplegando la Definicin de Errores en el Trigger Viendo los Triggers Definidos Borrando Triggers Desactivando Triggers Abortando Triggers con Error Mutating Table Errors

Difiriendo La Comprobacin de una Restriccin


A veces es necesario diferir la comprobacin de ciertas restricciones, como en el problema " del pollo-y-el-huevo". Suponga que nosotros queremos decir: CREATE TABLE Pollo (polloID INT PRIMARY KEY, huevoID INT REFERENCES Huevo(huevoID)); CREATE TABLE Huevo (huevoID INT PRIMARY KEY, polloID INT REFERENCES Pollo(polloID)); Pero si tecleamos las declaraciones anteriores en Oracle, nosotros conseguiremos un error. La razn es que la instruccin CREATE TABLE para Pollo se refiere a la tabla Huevo , que no se ha creado todava! Creando el Huevo no ayudarn mucho, porque el Huevo se refiere para un Pollo . Para trabajar alrededor de este problema, nosotros necesitamos comandos que permitan la modificacin del

esquema SQL. Primero, creamos el Pollo sin las declaraciones de llave fornea: CREATE TABLE Pollo (polloID INT PRIMARY KEY, huevoID INT); CREATE TABLE Huevo (huevoID INT PRIMARY KEY, polloID INT); Luego adicionamos las restricciones de llave fornea: ALTER TABLE Pollo ADD CONSTRAINT polloREFHuevo FOREIGN KEY (huevoID) REFERENCES Huevo (huevoID) INITIALLY DEFERRED DEFERRABLE; ALTER TABLE Huevo ADD CONSTRAINT huevoREFPollo FOREIGN KEY (polloID) REFERENCES Pollo (polloID) INITIALLY DEFERRED DEFERRABLE; INITIALLY DEFERRED DEFERRABLE le dice a Oracle que haga la comprobacin de restriccin diferida. Por ejemplo, para insertar (1, 2) en el pollo y (2, 1) en el huevo, nosotros usamos: INSERT INTO Pollo VALUES(1, 2); INSERT INTO Huevo VALUES(2, 1); COMMIT; Dado que hemos declarado las restricciones de llave fornea como "diferidas", ellos slo se verifican en el punto de Commit. (Sin diferir la verificacin de la restriccin, nosotros no podemos insertar nada en las tablas Pollo y Huevo, porque el primer INSERT siempre viola la restriccin). Finalmente, para borrar las tablas, primero tenemos que borrar las restricciones, porque Oracle no permite borrar una tabla que esta siendo referenciada por otra tabla. ALTER TABLE Huevo DROP CONSTRAINT huevoREFPollo; ALTER TABLE Pollo DROP CONSTRAINT polloREFHuevo; DROP TABLE Huevo; DROP TABLE Pollo;

Violacin de una Restriccin


En general, Oracle devuelve un mensaje del error cuando una restriccin se viola. Especficamente para los usuarios de JDBC, esto significa que se devuelve una SQLException. Los programadores deben usar la instruccin WHENEVER y/o verificar el contenido del SQLCA (para los usuarios de Pro*C) o capturar la excepcin SQLException (para usuarios de JDBC) para conseguir el cdigo de error devuelto por Oracle. Algunos nmeros del cdigo de error especficos son: 1 para las violaciones de restricciones de llave primaria, 2291 para las violaciones de llaves forneas, 2290 para las violaciones de restricciones CHECK de atributo y de tupla. Oracle tambin proporciona mensaje de error simples, que tienen un formato similar a lo siguiente: ORA-02290: check constraint (YFUNG.GR_GR) violated o ORA-02291: integrity constraint (HONDROUL.SYS_C0067174) violated - parent key not found

Para ms detalles sobre cmo es el manejo de errores, por favor eche una mirada al tratamiento de errores de Pro*C o a la seccin de las Recuperando Excepciones de tratamiento de errores de JDBC.

Sintaxis Bsica de un Trigger


A continuacin se presenta la sintaxis para crear un disparador en Oracle (difiere ligeramente de la sintaxis del SQL Standard): CREATE [OR REPLACE] TRIGGER < nombre_trigger > {BEFORE|AFTER} {INSERT|DELETE|UPDATE} ON <NombreTabla> [REFERENCING [NEW AS <nuevo_Nombre_Fila >] [OLD AS <Viejo_Nombre_Fila>]] [FOR EACH ROW [WHEN (<condicion_Del_Trigger >)]] <Cuerpo_Del_Trigger> Algunos puntos importantes para notar: Se pueden crear triggers para tablas, BEFORE y AFTER. ( Triggers INSTEAD OF solo estn disponibles para vistas; tpicamente ellos se usan para llevar a cabo actualizaciones de vistas.) Se pueden especificar hasta tres eventos de disparo usando el conector OR. Adems, UPDATE puede ser opcionalmente seguido de la palabra clave OF y una lista de atributos en <NombreTabla>. Si esta presente la clusula OF define que el evento solo ser una actualizacin del atributo(s) listados despus del OF. Aqu son algunos ejemplos: ... INSERT ON R ... ... INSERT OR DELETE OR UPDATE ON R ...
... UPDATE OF A, B OR INSERT ON R ...

Si se especifica la opcin FOR EACH ROW, el trigger es a nivel de fila; De otra forma el trigger ser a nivel de instruccin.. Slo para triggers a nivel de fila: Las variables especiales NEW y OLD estn disponibles para referirse respectivamente a las tuples nueva y vieja. Nota: En el cuerpo del disparador, NEW y OLD deben ser precedidos por dos puntos (":"), pero en la clusula WHEN, ellos no tienen los dos puntos precedentes! Vea el ejemplo debajo. La clusula REFERENCING puede ser usada para asignar alias a las variables NEW y OLD. Una restriccin trigger puede ser especificada en la clusula WHEN, encerrada entre parntesis. La restriccin del disparador es una condicin SQL que debe satisfacerse para que Oracle dispare el trigger. Esta condicin no puede contener subconsultas. Sin la clusula WHEN, el trigger se dispara para cada fila. El <Cuerpo_Del_Trigger> es un bloque PL/SQL, en lugar de una secuencia de instrucciones SQL. Oracle ha puesto ciertas restricciones sobre lo que usted puede hacer en el <Cuerpo_Del_Trigger>, para evitar situaciones dnde un disparador realiza una accin que activa un segundo trigger que entonces activa un tercero que podra crear, potencialmente, una vuelta infinita y as sucesivamente. Las restricciones sobre el <Cuerpo_Del_Trigger> incluyen:

Usted no puede modificar la misma relacin cuya modificacin es el evento que activa el disparador. Usted no puede modificar una relacin conectada a la relacin del disparador por otra restriccin como una llave fornea.

Ejemplo de Trigger
Nosotros ilustramos la sintaxis de Oracle por crear un disparador a travs de un ejemplo basado en las siguiente dos tablas: CREATE TABLE TA (a INTEGER, b CHAR(10)); CREATE TABLE TB (c CHAR(10), d INTEGER); Nosotros creamos un disparador que puede insertar un tupla en TB cuando un tupla se inserta en TA. Especficamente, el disparador verifica si la nueva tupla tiene un primer componente 10 o menos, y en ese caso inserta la tupla inversa en TB:

CREATE TRIGGER dispara1 AFTER INSERT ON TA REFERENCING NEW AS nuevaFila FOR EACH ROW WHEN (nuevaFila.a <= 10) BEGIN INSERT INTO TB VALUES(:nuevaFila.b, : nuevaFila.a); END dispara1; . run; Note que la instruccin CREATE TRIGGER la finalizamos con punto y run, como en todas las declaraciones de PL/SQL. La ejecucin de la instruccin CREATE TRIGGER solo crea el trigger, no lo ejecuta. Slo un evento de activacin, como una insercin en TA (para este ejemplo), causa que el trigger se ejecute.

Desplegando la Definicin de Errores en el Trigger


Como en los procedimientos de PL/SQL, si usted obtiene un mensaje Warning: Trigger created with compilation errors. usted puede ver los mensajes del error tecleando show errors trigger <trigger_name>; Alternativamente, usted puede digitar, SHO ERR (abreviando por SHOW ERRORS) para ver el ms reciente error de la compilacin. Observe que el nmero de la lnea donde se reporta que ocurren los errores ocurren no es exacta.

Viendo los Triggers Definidos


Para ver una lista de todos los disparadores definidos, se usa la consulta: select trigger_name from user_triggers; Para ms detalles sobre un trigger en particular: select trigger_type, triggering_event, table_name, referencing_names, trigger_body from user_triggers where trigger_name = '<Nombre_Trigger>';

Borrando Triggers
Para borrar un trigger ejecuto la instruccin: drop trigger <Nombre_Trigger>;

Desactivando Triggers
Para desactivar o activar un trigger: alter trigger <Nombre_Trigger> {disable|enable};

Abortando Triggers con Error


Los disparadores pueden usarse a menudo para reforzar a una restriccin. La clusula WHEN o el cuerpo del disparador pueden verificar la violacin de ciertas condiciones y pueden sealar un error que usando la funcin incorporada RAISE_APPLICATION_ERROR del Oracle. La accin que activ el trigger (la insercin, actualizacin, o borrado) se abortara. Por ejemplo, el siguiente trigger refuerza la restriccin de que la edad de la persona sea mayor o igual que cero ( Persona.edad >= 0): create table Persona (edad int); CREATE TRIGGER ChequeaEdadPersona AFTER INSERT OR UPDATE OF edad ON Persona FOR EACH ROW BEGIN IF (:new.edad < 0) THEN RAISE_APPLICATION_ERROR(-20000, 'No se permite una edad negativa'); END IF; END; . RUN; Si intentamos ejecutar la insercin: insert into Person values (-3); Obtendremos el siguiente mensaje de error: ERROR at line 1: ORA-20000: No se permite una edad negativa ORA-06512: at "MYNAME.CHEQUEAEDADPERSONA", line 3 ORA-04088: error during execution of trigger 'MYNAME.CHEQUEAEDADPERSONA' y nada se insertar. En general, los efectos del trigger y la declaracin de activacin son reversadas..

Errores de Tabla Mutante


A veces usted puede encontrar que Oracle informa un" error de tabla mutante" ("mutating table error") cuando su trigger se ejecuta. Esto sucede cuando el disparador est preguntando o est modificando una" tabla mutante" la cual es la tabla cuya modificacin activ el disparador o una tabla que podra necesitar actualizarse debido a una restriccin de llave fornea con una poltica en cascada (CASCADE). Para evitar errores de tabla mutante: Un trigger a nivel de fila no debe preguntar o modificar una tabla mutante. (por su puesto que NEW y OLD todava puede accederse por el disparador.) Un trigger a nivel de instruccin no debe preguntar o modificar una tabla mutante si el trigger se dispara como resultado de un borrado en cascada.

Referencias
[1] http://www-db.stanford.edu/~ullman/fcdb/oracle/or-nonstandard.html#constraints

Anda mungkin juga menyukai