144 - Disparador de actualización (update trigger)


Problema:

Una librería 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 tablas, 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 actualización 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 actualización. Podemos comprobarlo consultando la tabla "libros".

Eliminamos el disparador creado anteriormente (tema que veremos más adelante):

 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 transacción.

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 transacción. 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 transacción; el registro no fue actualizado, verificamos:

 select *from libros;

Eliminamos el disparador creado anteriormente:

 drop trigger DIS_libros_actualizar_precio;

Creamos un disparador de actualización que muestra el valor anterior y nuevo valor de los registros actualizados. El trigger debe controlar que la actualización se realice en los campos "titulo", "autor" y "editorial" y no en los demás 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 transacción:

 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 actualización 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 después de la transacción.

Veamos qué sucede si en la sentencia "update" intentamos modificar algún campo no permitido:

 update libros set editorial='Paidos', precio=30 where codigo>3;

El trigger se dispara y muestra el mensaje de error, la transacción no se realizó.

Intentamos modificar el código de un libro:

 update libros set codigo=9 where codigo>=3; 

El disparador no llega a dispararse porque SQL Server muestra un mensaje de error ya que el campo "codigo", por ser "identity", no puede modificarse.




Retornar