60 - Disparadores (triggers) cláusula when

Hemos dicho que la sintaxis general de un disparador es:

create trigger [if not exists] nombre-del-trigger
   [before o after o instead of] [insert o delete o update] 
   on nombre-de-la-tabla
   [when condición]
begin
 instrucciones-sql;
end;

La cláusula when es opcional como hemos visto anteriormente. En el caso que la especifiquemos tiene por objetivo condicionar la ejecución del disparador dependiendo del resultado de dicho when.

Si se usa una condición en la cláusula 'when', el disparador o trigger solo se invoca cuando la condición es verdadera. En caso de que se omita la cláusula 'when', el disparador se ejecuta para todas las filas.

Problema resuelto

Necesitamos almacenar en una tabla llamada "usuarios" los datos de los usuarios de un sitio web. Cada vez que el usuario cambia su clave se debe almacenar en otra tabla llamada "clavesanteriores" el dato de la clave vieja siempre y cuando la clave sea distinta a la actual.

Borramos las dos tablas si existen:

drop table if exists usuarios;
drop table if exists clavesanteriores;

Creamos ambas tablas con las siguientes estructuras:

create table usuarios(
 nombre text primary key,
 clave text
);

create table clavesanteriores(
  nombre text,
  clave text
);

Si existe el trigger 'disparador_claves_anteriores' procedemos a borrarlo:

drop trigger if exists disparador_claves_anteriores;

Creamos el trigger 'disparador_claves_anteriores':

create trigger disparador_claves_anteriores
   before update
   on usuarios
   when new.clave<>old.clave
begin
   insert into clavesanteriores(nombre, clave) values (old.nombre, old.clave); 
end;

Este trigger se ejecutará cada vez que ejecutemos el comando SQL 'update' con la tabla 'usuarios':

   before update
   on usuarios

Mediante la cláusula 'when' condicionamos que el disparador se ejecute si la clave nueva que pasamos en el comando 'update' es distinta a la clave anterior que tiene definida ese usuario:

   when new.clave<>old.clave

El bloque del disparador se encuentra encerrado entre las palabras claves 'begin' y 'end'. Nuestro algoritmo es ejecutar un comando SQL insert en la tabla 'clavesanteriores' insertando el nombre de usuario y clave previo a ser cambiado por el comando 'update' en la tabla 'usuarios'.

Ejecutemos ahora un insert en la tabla 'usuarios':

insert into usuarios(nombre,clave) values ('marcos','123abc');

El trigger no se ejecuta ya que solo hemos definido que se dispare para el comando 'update'.

Ahora procedamos a modificar la clave del usuario mediante el comando 'update':

update usuarios set clave='abcdef' where nombre='marcos';

Cuando se ejecuta el 'update' además de actualizarse la clave del usuario en la tabla 'usuarios' se verifica si se tiene que ejecutar el trigger dependiendo del cláusula 'when':

   when new.clave<>old.clave

Para este ejemplo estamos preguntando:

   when 'abcdef'<>'123abc'

Como podemos comprobar las dos cadenas son distintas y por lo tanto se ejecuta el bloque del trigger procediendo a almacenar una fila en la tabla 'clavesanteriores'.

Listemos la tabla 'clavesanteriores'

select * from clavesanteriores;

Podemos comprobar que tenemos ahora una fila que contiene los datos:

nombre: marcos
clave: 123abc

Si ejecutamos otro 'update' pero cambiando la clave con la clave actual:

update usuarios set clave='abcdef' where nombre='marcos';

La cláusula 'when' evita que se ejecute el trigger y por lo tanto la inserción de una nueva fila en la tabla 'clavesanteriores'.

Listamos nuevamente la tabla 'clavesanteriores':

select * from clavesanteriores;

Podemos comprobar que seguimos teniendo una fila:

nombre: marcos
clave: 123abc

Ejecución de ejercicios online

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

Resultado.....