59 - Disparadores (triggers) update

Hemos visto en conceptos anteriores la creación de disparadores cuando se ejecutan los comandos insert y delete en una tabla. Ahora veremos con un ejemplo como asociar un trigger a una tabla para cuando se ejecuta el comando update.

Problema resuelto

Una librería almacena los datos de sus libros en una tabla denominada "libros".
Eliminamos la tabla "libros" si existe:

drop table if exists libros;

Creamos la tabla "libros" con la siguiente estructura:

 create table libros(
  codigo integer primary key,
  titulo text,
  autor text,
  editorial text,
  precio real, 
  stock integer
 );

Almacenamos 4 filas en la tabla "libros":

 insert into libros(titulo, autor, editorial, precio, stock)
  values('Uno','Richard Bach','Planeta',15,100);   
 insert into libros(titulo, autor, editorial, precio, stock)
  values('Ilusiones','Richard Bach','Planeta',18,50);
 insert into libros(titulo, autor, editorial, precio, stock)
  values('El aleph','Borges','Emece',25,200);
 insert into libros(titulo, autor, editorial, precio, stock)
  values('Aprenda PHP','Mario Molina','Emece',45,200); 

Modificamos el precio del libro con código 1 con el valor 500:

 update libros set precio=500 where codigo=1;

Si imprimimos la tabla "libros" podemos comprobar que el libro con código 1 tiene un nuevo precio:

 select * from libros;

Crearemos un trigger que congele los precios de todos los libros, es decir que no se le puedan cambiar su precio:

 create trigger disparador_congelar_precios_libros
   before update on libros
 begin
   select
     case when new.precio<>old.precio THEN
       raise ( ABORT, 'Los precios de los libros estan congelados, no se pueden cambiar')
     end
     from libros where new.codigo=libros.codigo; 
 end;    

Intentemos ahora cambiar nuevamente el precio del libro con código 1:

update libros set precio=1000 where codigo=1;

Como podemos comprobar ahora se ejecuta el trigger "disparador_congelar_precios_libros" donde se verifica si el nuevo precio es distinto al viejo precio se eleva una excepción y se evitan los cambios en la tabla "libros":

SQLite Browser trigger update

Ahora procedamos a eliminar el trigger "disparador_congelar_precios_libros":

 drop trigger disparador_congelar_precios_libros;

Ahora si podemos modificar nuevamente los precios de los libros:

 update libros set precio=1000 where codigo=1;

 select * from libros;

SQLite Browser trigger update

Problema propuesto

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 y deportes de los socios que deben matrículas.

  1. Borrar las tres tablas si existen.

  2. Cree las tablas, con las siguientes estructuras:

     create table socios(
      documento text primary key,
      nombre text,
      domicilio text
     );
    
     create table inscriptos(
      numero integer primary key,
      documento text,
      deporte text,
      matricula text
     );
     
     create table morosos(
      documento text,
      deporte text,
      primary key(documento,deporte)
     );
    
    
  3. Almacenar los siguientes datos de ejemplo:

     insert into socios(documento,nombre,domicilio)
      values('22222222','Ana Acosta','Avellaneda 800');
     insert into socios(documento,nombre,domicilio)
      values('23333333','Bernardo Bustos','Bulnes 345');
     insert into socios(documento,nombre,domicilio)
      values('24444444','Carlos Caseros','Colon 382');
     insert into socios(documento,nombre,domicilio)
      values('25555555','Mariana Morales','Maipu 234');
    
     insert into inscriptos(documento,deporte,matricula)
      values('22222222','tenis','s');
     insert into inscriptos(documento,deporte,matricula)
      values('22222222','natacion','n');
     insert into inscriptos(documento,deporte,matricula)
      values('23333333','tenis','n');
     insert into inscriptos(documento,deporte,matricula)
      values('24444444','futbol','s');
     insert into inscriptos(documento,deporte,matricula)
      values('24444444','natacion','s');
    
     insert into morosos(documento,deporte) values('22222222','natacion');
     insert into morosos(documento,deporte) values('23333333','tenis'); 
    
  4. Crear un trigger que cuando se modifique la matricula de un socio para un determinado deporte por el valor 's' proceda a eliminarlo de la tabla "morosos".

  5. Ejecutar el siguiente 'update' en la tabla "inscriptos":

     update inscriptos set matricula='s' where documento='22222222' and deporte='natacion';
    
  6. Imprimir la tabla "morosos" y verificar si mediante el trigger creado se ha eliminado una fila.

Solución
drop table if exists inscriptos;
drop table if exists socios;
drop table if exists morosos;

 create table socios(
  documento text primary key,
  nombre text,
  domicilio text
 );

 create table inscriptos(
  numero integer primary key,
  documento text,
  deporte text,
  matricula text
 );
 
 create table morosos(
  documento text,
  deporte text,
  primary key(documento,deporte)
 );
 
 insert into socios(documento,nombre,domicilio)
  values('22222222','Ana Acosta','Avellaneda 800');
 insert into socios(documento,nombre,domicilio)
  values('23333333','Bernardo Bustos','Bulnes 345');
 insert into socios(documento,nombre,domicilio)
  values('24444444','Carlos Caseros','Colon 382');
 insert into socios(documento,nombre,domicilio)
  values('25555555','Mariana Morales','Maipu 234');

 insert into inscriptos(documento,deporte,matricula)
  values('22222222','tenis','s');
 insert into inscriptos(documento,deporte,matricula)
  values('22222222','natacion','n');
 insert into inscriptos(documento,deporte,matricula)
  values('23333333','tenis','n');
 insert into inscriptos(documento,deporte,matricula)
  values('24444444','futbol','s');
 insert into inscriptos(documento,deporte,matricula)
  values('24444444','natacion','s');

 insert into morosos(documento,deporte) values('22222222','natacion');
 insert into morosos(documento,deporte) values('23333333','tenis'); 
 
 create trigger disparador_pago_matricula
   before update on inscriptos
 begin
   delete from morosos where documento=new.documento and deporte=new.deporte and new.matricula='s';
 end; 
 
 update inscriptos set matricula='s' where documento='22222222' and deporte='natacion';
 
 select * from morosos;
 

Ejecución de ejercicios online

Puede ejecutar comandos de SQLite directamente en el sitio sin tener que instalar nada en su computadora.

Resultado.....