You are on page 1of 14

Ms SQL Server 2000

IESTP PAIJN

Tema : Disparadores - Trigger Un "trigger" (disparador o desencadenador) es un tipo de procedimiento almacenado que se ejecuta cuando se intenta modificar los datos de una tabla (o vista). Se definen para una tabla (o vista) especfica. Se crean para conservar la integridad referencial y la coherencia entre los datos entre distintas tablas. Si se intenta modificar (agregar, actualizar o eliminar) datos de una tabla en la que se defini un disparador para alguna de estas acciones (insercin, actualizacin y eliminacin), el disparador se ejecuta (se dispara) en forma automtica. Un trigger se asocia a un evento (insercin, actualizacin o borrado) sobre una tabla. La diferencia con los procedimientos almacenados del sistema es que los triggers: - No pueden ser invocados directamente; al intentar modificar los datos de una tabla para la que se ha definido un disparador, el disparador se ejecuta automticamente. - No reciben y retornan parmetros. - Son apropiados para mantener la integridad de los datos, no para obtener resultados de consultas. Los disparadores, a diferencia de las restricciones "check", pueden hacer referencia a campos de otras tablas. Por ejemplo, puede crearse un trigger de insercin en la tabla "ventas" que compruebe el campo "stock" de un artculo en la tabla "articulos"; el disparador controlara que, cuando el valor de "stock" sea menor a la cantidad que se intenta vender, la insercin del nuevo registro en "ventas" no se realice. Los disparadores se ejecutan DESPUES de la ejecucin de una instruccin "insert", "update" o "delete" en la tabla en la que fueron definidos. Las restricciones se comprueban ANTES de la ejecucin de una instruccin "insert", "update" o "delete". Por lo tanto, las restricciones se comprueban primero, si se infringe alguna restriccin, el desencadenador no llega a ejecutarse. Los Triggers se crean con la instruccin "create trigger". Esta instruccin especifica la tabla en la que se define el disparador, los eventos para los que se ejecuta y las instrucciones que contiene. Sintaxis bsica: Create Trigger NOMBREDISPARADOR ON NOMBRETABLA FOR EVENTO- insert, update o delete AS SENTENCIAS Analizamos la sintaxis: - "Create Trigger" junto al nombre del disparador. - "On" seguido del nombre de la tabla o vista para la cual se establece el trigger. - luego de "For", se indica la accin (evento, el tipo de modificacin) sobre la tabla o vista que activar el trigger. Puede ser "insert", "update" o "delete". Debe colocarse al menos UNA accin, si se coloca ms de una, deben separarse con comas.

Mg. Alberto Guillermo Villar Paredes

Ms SQL Server 2000

IESTP PAIJN

luego de "as" viene el cuerpo del trigger, se especifican las condiciones y acciones del disparador; es decir, las condiciones que determinan cuando un intento de insercin, actualizacin o borrado provoca las acciones que el trigger realizar.

Consideraciones generales: - "create trigger" debe ser la primera sentencia de un bloque y slo se puede aplicar a una tabla. - un disparador se crea solamente en la base de datos actual pero puede hacer referencia a objetos de otra base de datos. - Las siguientes instrucciones no estn permitidas en un desencadenador: create database, alter database, drop database, load database, restore database, load log, reconfigure, restore log, disk init, disk resize. - Se pueden crear varios triggers para cada evento, es decir, para cada tipo de modificacin (insercin, actualizacin o borrado) para una misma tabla. Por ejemplo, se puede crear un "insert trigger" para una tabla que ya tiene otro "insert trigger". Caso Creamos un trigger sobre la tabla "ventas" para el evento se insercin. Cada vez que se realiza un "insert" sobre "ventas", el disparador se ejecuta. El disparador controla que la cantidad que se intenta vender sea menor o igual al stock del libro y actualiza el campo "stock" de "libros", restando al valor anterior la cantidad vendida: Create Trigger DIS_ventas_insertar On ventas For insert As Declare @stock int select @stock= stock from libros join inserted on inserted.codigolibro=libros.codigo where libros.codigo=inserted.codigolibro if (@stock>=(select cantidad from inserted)) update libros set stock=stock-inserted.cantidad from libros join inserted on inserted.codigolibro=libros.codigo where codigo=inserted.codigolibro else begin raiserror ('Hay menos libros en stock de los solicitados para la venta', 16, 1) rollback transaction end Entonces, creamos el disparador ("create trigger") dndole un nombre ("DI_ventas_insertar") sobre ("on") una tabla especfica ("ventas") para ("for") el suceso de insercin ("insert"). Luego se "as" colocamos las sentencias, las acciones que el trigger realizar cuando se ingrese

Mg. Alberto Guillermo Villar Paredes

Ms SQL Server 2000

IESTP PAIJN

un registro en "ventas" (en este caso, controlar que haya stock y disminuir el stock de "libros"). Cuando se activa un disparador "insert", los registros se agregan a la tabla del disparador y a una tabla denominada "inserted". La tabla "inserted" es una tabla virtual que contiene una copia de los registros insertados; tiene una estructura similar a la tabla en que se define el disparador, es decir, la tabla en que se intenta la accin. La tabla "inserted" guarda los valores nuevos de los registros. Dentro del trigger se puede acceder a esta tabla virtual "inserted" que contiene todos los registros insertados, es lo que hicimos en el disparador creado anteriormente, lo que solicitamos es que se le reste al "stock" de "libros", la cantidad ingresada en el nuevo registro de "ventas", valor que recuperamos de la tabla "inserted". "rollback transaction" es la sentencia que deshace la transaccin, es decir, borra todas las modificaciones que se produjeron en la ltima transaccin restableciendo todo al estado anterior. "raiserror" muestra un mensaje de error personalizado. El disparador del siguiente ejemplo se crea para la tabla "ventas", para que cada vez que se elimine un registro de "ventas", se actualice el campo "stock" de la tabla "libros" (por ejemplo, si el comprador devuelve los libros comprados): Create Trigger DIS_ventas_borrar on ventas for delete As update libros set stock= libros.stock+deleted.cantidad from libros join deleted on deleted.codigolibro=libros.codigo; Entonces, creamos el disparador ("create trigger") dndole un nombre ("DI_ventas_borrar") sobre ("on") una tabla especfica ("ventas") para ("for") el evento de borrado ("delete"). Luego de "as" colocamos las sentencias, las acciones que el trigger realizar cuando se elimine un registro en "ventas" (en este caso, aumentar el stock de "libros"). Cuando se activa un disparador "delete", los registros eliminados en la tabla del disparador se agregan a una tabla llamada "deleted". La tabla "deleted" es una tabla virtual que conserva una copia de los registros eliminados; tiene una estructura similar a la tabla en que se define el disparador, es decir, la tabla en que se intenta la accin. Dentro del trigger se puede acceder a esta tabla virtual "deleted". Al eliminar un registro en la Tabla Ventas se acivar el Trigger Delete from ventas where numero=1
Mg. Alberto Guillermo Villar Paredes 3

Ms SQL Server 2000

IESTP PAIJN

El siguiente disparador se crea para controlar que no se elimine ms de un registro de la tabla "libros". El disparador se activa cada vez que se elimina un registro o varios, controlando la cantidad de registros que se estn eliminando; si se est eliminando ms de un registro, el disparador retorna un mensaje de error y deshace la transaccin: Create Trigger DIS_libros_borrar on libros for delete As if (select count(*) from deleted) > 1 begin raiserror('No puede borrar ms de un libro',16,1) rollback transaction end Si se ejecuta un "delete" sobre "libros" que afecte a varios registros, se activa el disparador y evita la transaccin. Si se ejecuta el siguiente "delete", que afecta a un solo registro, se activa el disparador y permite la transaccin: delete from libros where codigo=5;

CREATE DATABASE VENTALIBROS USE VENTALIBROS Create Table Libros( codigo int identity, titulo varchar(40), autor varchar(30), editorial varchar(20), precio decimal(6,2), cantidad int, primary key (codigo) ) Create Table Ventas ( numero int identity, codigo int not null, preciounitario decimal(6,2), cantidad int, constraint PK_ventas primary key (numero), constraint FK_ventas_codigolibro foreign key (codigo) references libros(codigo) on update cascade )

Mg. Alberto Guillermo Villar Paredes

Ms SQL Server 2000

IESTP PAIJN

Ingrese algunos registros para ambas: insert into libros values('Uno','Richard Bach','Planeta',15,100); insert into libros values('Ilusiones','Richard Bach','Planeta',18,150); insert into libros values('El aleph','Borges','Emece',25,200); insert into libros values('Matematica estas ahi','Paenza','Nuevo siglo',20,300); insert into libros values('Aprenda PHP','Mario Molina','Nuevo siglo',45,200); insert into ventas values(1,15,1) insert into ventas values(2,18,1) insert into ventas values(3,25,100) insert into ventas values(1,15,50) CASO DESARROLLADO Un comercio que vende artculos de informtica almacena los datos de sus artculos en una tabla denominada "articulos". 1- Elimine la tabla si existe: if object_id('articulos') is not null Drop Table Articulos; 2- Cree la tabla, con la siguiente estructura: Create Table articulos( codigo int identity, tipo varchar(30), descripcion varchar(40), precio decimal(8,2), stock int, constraint PK_articulos primary key (codigo) ) 3- Ingrese algunos registros: insert into articulos values ('impresora','Epson Stylus C45',400,100); insert into articulos values ('impresora','Epson Stylus C85',500,200); insert into articulos values ('impresora','Epson Stylus Color 600',400,0); insert into articulos values ('monitor','Samsung 14',900,0); insert into articulos values ('monitor','Samsung 17',1200,0); insert into articulos values ('monitor','xxx 15',1500,0); insert into articulos values ('monitor','xxx 17',1600,0); insert into articulos values ('monitor','zzz 15',1300,0); 4- Cree un disparador para controlar que no se elimine un artculo si hay stock. El disparador se activar cada vez que se ejecuta un "delete" sobre "articulos", controlando el stock, si se est eliminando un artculo cuyo stock sea mayor a 0, el disparador debe retornar un mensaje de error y deshacer la transaccin. 5- Solicite la eliminacin de un articulo que no tenga stock. Se activa el disparador y permite la transaccin.
Mg. Alberto Guillermo Villar Paredes 5

Ms SQL Server 2000

IESTP PAIJN

6- Intente eliminar un artculo para el cual haya stock. El trigger se dispara y deshace la transaccin. Puede verificar que el artculo no fue eliminado consultando la tabla "articulos". 7- Solicite la eliminacin de varios artculos que no tengan stock. Se activa el disparador y permite la transaccin. Puede verificar que se borraron 2 artculos consultando la tabla "articulos". 8- Intente eliminar varios artculos, algunos con stock y otros sin stock. El trigger se dispara y deshace la transaccin, es decir, ningn artculo fue eliminado, tampoco los que tienen stock igual a 0. 9- Cree un trigger para evitar que se elimine ms de 1 artculo. Note que hay 2 disparadores para el mismo suceso (delete) sobre la misma tabla. 10- Solicite la eliminacin de 1 artculo para el cual no haya stock. Ambos disparadores "DIS_articulos_borrar" y "DIS_articulos_borrar2" se activan y permiten la transaccin. 11- Solicite la eliminacin de 1 artculo que tenga stock. El disparadores "DIS_articulos_borrar" se activa y no permite la transaccin. El disparador "DIS_articulos_borrar2" no llega a activarse. 12- Solicite la eliminacin de 2 artculos para los cuales no haya stock. El disparador "DIS_articulos_borrar" se activa y permite la transaccin pero el disparador "DIS_articulos_borrar2" no permite la transaccin. 13- Solicite la eliminacin de 2 artculos para los que haya stock. El disparador "DIS_articulos_borrar" se activa y no permite la transaccin. El disparador "DIS_articulos_borrar2" no llega a activarse. Solucin if object_id('articulos') is not null drop table articulos; Create Table Articulos( codigo int identity, tipo varchar(30), descripcion varchar(40), precio decimal(8,2), stock int, constraint PK_articulos primary key (codigo) ) insert into articulos values ('impresora','Epson Stylus C45',400,100);
Mg. Alberto Guillermo Villar Paredes 6

Ms SQL Server 2000

IESTP PAIJN

insert into articulos values ('impresora','Epson Stylus C85',500,200); insert into articulos values ('impresora','Epson Stylus Color 600',400,0); insert into articulos values ('monitor','Samsung 14',900,0); insert into articulos values ('monitor','Samsung 17',1200,0); insert into articulos values ('monitor','xxx 15',1500,0); insert into articulos values ('monitor','xxx 17',1600,0); insert into articulos values ('monitor','zzz 15',1300,0); Create Trigger DIS_articulos_borrar on articulos for delete As if exists(select *from deleted where stock>0)--si algun registro borrado tiene stock begin raiserror('No puede eliminar artculos que tienen stock',16,1) rollback transaction end else begin declare @cantidad int select @cantidad=count(*) from deleted select 'Se eliminaron ' +rtrim(cast(@cantidad as char(10)))+ ' registros' end delete from articulos where codigo=4 delete from articulos where codigo=2 delete from articulos where descripcion like '%xx%' delete from articulos where codigo<=3 Create Trigger DIS_articulos_borrar2 on articulos for delete As declare @cantidad int select @cantidad=count(*) from deleted if @cantidad>1 begin raiserror('No puede eliminar ms de 1 artculo',16,1) rollback transaction end delete from articulos where codigo=3 delete from articulos where codigo=2 delete from articulos where tipo='monitor'
Mg. Alberto Guillermo Villar Paredes 7

Ms SQL Server 2000

IESTP PAIJN

delete from articulos where tipo='impresora' CASO DESARROLLADO Una librera almacena los datos de sus libros en una tabla denominada "libros". Eliminamos la tabla si existe: if object_id('libros') is not null drop table libros Creamos la tabla, con la siguiente estructura: create table libros( codigo int identity, titulo varchar(40), autor varchar(30), editorial varchar(20), precio decimal(6,2), stock int, constraint PK_libros primary key(codigo) ) Ingresamos algunos registros en "libros": insert into libros values('Uno','Richard Bach','Planeta',15,100); insert into libros values('Alicia en el pais...','Lewis Carroll','Planeta',18,50); insert into libros values('El aleph','Borges','Emece',25,200); insert into libros values('Aprenda PHP','Mario Molina','Nuevo siglo',45,200); Creamos un disparador para evitar que se modifiquen los datos de la tabla "libros": Create Trigger DIS_libros_actualizar on libros for update As raiserror('Los datos de la tabla "libros" no pueden modificarse', 10, 1) rollback transaction; Intentamos realizar alguna actualizacin en "libros": update libros set titulo='Alicia en el pais de las maravillas' where codigo=2; El disparador se activ, mostr un mensaje y deshizo la actualizacin. Podemos comprobarlo consultando la tabla "libros".

Mg. Alberto Guillermo Villar Paredes

Ms SQL Server 2000

IESTP PAIJN

Eliminamos el disparador creado anteriormente drop trigger DIS_libros_actualizar; Creamos un disparador que evite que se actualice el campo "precio" de la tabla "libros": Create Trigger DIS_libros_actualizar_precio on libros for update As if update(precio) begin raiserror('El precio de un libro no puede modificarse.', 10, 1) rollback transaction end; Veamos qu sucede si intentamos actualizar el precio de un libro: update libros set precio=30 where codigo=2; El disparador se activa, muestra un mensaje y deshace la transaccin. Veamos qu sucede al actualizar el campo "titulo": update libros set titulo='Alicia en el pais de las maravillas' where codigo=2; El disparador se activa y realiza la transaccin. Lo verificamos consultando la tabla: select *from libros; Veamos qu sucede si intentamos actualizar el precio y la editorial de un libro: update libros set precio=30,editorial='Emece' where codigo=1; El disparador se activa, muestra un mensaje y deshace la transaccin; el registro no fue actualizado, verificamos: select * from libro Eliminamos el disparador creado anteriormente: drop trigger DIS_libros_actualizar_precio

Mg. Alberto Guillermo Villar Paredes

Ms SQL Server 2000

IESTP PAIJN

Creamos un disparador de actualizacin que muestra el valor anterior y nuevo valor de los registros actualizados. El trigger debe controlar que la actualizacin se realice en los campos "titulo", "autor" y "editorial" y no en los dems campos (precio y stock)); si se modifican los campos permitidos y ninguno de los no permitidos, mostrar los antiguos y nuevos valores consultando las tablas "deleted" e "inserted", en caso que se actualice un campo no permitido, el disparador muestra un mensaje y deshace la transaccin: Create Trigger DIS_libros_actualizar2 on libros for update as if (update(titulo) or update(autor) or update(editorial)) and not (update(precio) or update(stock)) begin select (d.titulo+'-'+ d.autor+'-'+d.editorial) as 'registro anterior', (i.titulo+'-'+ i.autor+'-'+i.editorial) as 'registro actualizado' from deleted as d join inserted as i on d.codigo=i.codigo end else begin raiserror('El precio y stock no pueden modificarse. La actualizacin no se realiz.', 10, 1) rollback transaction end Veamos qu sucede si modificamos campos permitidos: update libros set editorial='Paidos', autor='Desconocido' where codigo>3; El trigger se dispara y muestra los registros modificados, los valores antes y despus de la transaccin. Veamos qu sucede si en la sentencia "update" intentamos modificar algn campo no permitido: update libros set editorial='Paidos', precio=30 where codigo>3 El trigger se dispara y muestra el mensaje de error, la transaccin no se realiz. Intentamos modificar el cdigo de un libro: update libros set codigo=9 where codigo>=3

Mg. Alberto Guillermo Villar Paredes

10

Ms SQL Server 2000

IESTP PAIJN

Un club almacena los datos de sus socios en una tabla denominada "socios", las inscripciones en "inscriptos" y en otra tabla "morosos" guarda los documentos de los socios que deben matrculas. 1- Elimine las tablas si existen: if object_id('inscriptos') is not null drop table inscriptos; if object_id('socios') is not null drop table socios; if object_id('morosos') is not null drop table morosos; 2- Cree las tablas, con las siguientes estructuras: create table socios( documento char(8) not null, nombre varchar(30), domicilio varchar(30), constraint PK_socios primary key(documento) ); create table inscriptos( numero int identity, documento char(8) not null, deporte varchar(20), matricula char(1), constraint FK_inscriptos_documento foreign key (documento) references socios(documento), constraint CK_inscriptos_matricula check (matricula in ('s','n')), constraint PK_inscriptos primary key(documento,deporte) ); create table morosos( documento char(8) not null ); 3- Ingrese algunos registros en las 3 tablas: insert into socios values('22222222','Ana Acosta','Avellaneda 800'); insert into socios values('23333333','Bernardo Bustos','Bulnes 345'); insert into socios values('24444444','Carlos Caseros','Colon 382'); insert into socios values('25555555','Mariana Morales','Maipu 234'); insert into inscriptos values('22222222','tenis','s'); insert into inscriptos values('22222222','natacion','n'); insert into inscriptos values('23333333','tenis','n');
Mg. Alberto Guillermo Villar Paredes 11

Ms SQL Server 2000

IESTP PAIJN

insert into inscriptos values('24444444','futbol','s'); insert into inscriptos values('24444444','natacion','s'); insert into morosos values('22222222'); insert into morosos values('23333333'); 4- Cree un disparador para la tabla "inscriptos" que se active ante una sentencia "update" y no permita actualizar ms de un registro. 5- Cree otro disparador para la tabla "inscriptos" que se active ante una sentencia "update". Si se actualiza el pago de la matrcula a 's', el socio debe eliminarse de la tabla "morosos"; no debe permitir modificar a 'n' una matrcula paga. 6- Actualice cualquier campo (diferente de "matricula") de un registro de la tabla "inscriptos". Ambos disparadores se activaron permitiendo la transaccin. 7- Actualice cualquier campo (diferente de "matricula") de varios registros de la tabla "inscriptos". El disparador "dis_inscriptos_actualizar1" se activa y no permite la transaccin. El disparador "dis_inscriptos_actualizar_matricula" no llega a activarse. 8- Actualice el campo "matricula" a 's' de un inscripto que deba la matrcula. Ambos disparadores se activaron y permitieron la actualizacin. 9- Verifique que el campo se actualiz y que el socio ya no est en "morosos": select *from inscriptos; select *from morosos; 10-Actualice el campo "matricula" a 'n' de un inscripto que tenga la matrcula paga. Ambos disparadores se activaron; "dis_inscriptos_actualizar_matricula" deshace transaccin. Solucin if object_id('inscriptos') is not null drop table inscriptos; if object_id('socios') is not null drop table socios; if object_id('morosos') is not null drop table morosos; create table socios( documento char(8) not null, nombre varchar(30), domicilio varchar(30),
Mg. Alberto Guillermo Villar Paredes 12

la

Ms SQL Server 2000

IESTP PAIJN

constraint PK_socios primary key(documento) ); create table inscriptos( numero int identity, documento char(8) not null, deporte varchar(20), matricula char(1), constraint FK_inscriptos_documento foreign key (documento) references socios(documento), constraint CK_inscriptos_matricula check (matricula in ('s','n')), constraint PK_inscriptos primary key(documento,deporte) ); create table morosos( documento char(8) not null ); insert into socios values('22222222','Ana Acosta','Avellaneda 800'); insert into socios values('23333333','Bernardo Bustos','Bulnes 345'); insert into socios values('24444444','Carlos Caseros','Colon 382'); insert into socios values('25555555','Mariana Morales','Maipu 234'); insert into inscriptos values('22222222','tenis','s'); insert into inscriptos values('22222222','natacion','n'); insert into inscriptos values('23333333','tenis','n'); insert into inscriptos values('24444444','futbol','s'); insert into inscriptos values('24444444','natacion','s'); insert into morosos values('22222222'); insert into morosos values('23333333'); create trigger DIS_inscriptos_actualizar1 on inscriptos for update as if (select count(*) from deleted) > 1 begin raiserror('No puede actualizar ms de un registro',16,1) rollback transaction end; create trigger DIS_inscriptos_actualizar_matricula
Mg. Alberto Guillermo Villar Paredes 13

Ms SQL Server 2000

IESTP PAIJN

on inscriptos for update as if update(matricula) if (select matricula from inserted)='n' and (select matricula from deleted)='s' begin raiserror('No puede colocar impaga una cuota paga.', 16, 1) rollback transaction end else if (select matricula from inserted)='s' and (select matricula from deleted)='n' delete morosos from morosos join deleted on deleted.documento=morosos.documento where morosos.documento=deleted.documento; update inscriptos set deporte='basquet' where numero=1; update inscriptos set deporte='basquet' where numero between 3 and 4; update inscriptos set matricula='s' where numero=2; select *from inscriptos; select *from morosos; update inscriptos set matricula='n' where numero=2;

Mg. Alberto Guillermo Villar Paredes

14

You might also like