Un trigger, come suggerisce il nome (grilletto), è un insieme di istruzioni che si eseguono, o vengono attivate, quando un dato evento avviene su una tabella.

L'evento può essere una INSERT, una UPDATE o una DELETE.

Creare un trigger

Ecco un semplice esempio per vedere un trigger in azione. Utilizzeremo come esempio queste due tabelle:

MariaDB [test]> CREATE TABLE animals (id mediumint(9) 
NOT NULL AUTO_INCREMENT, 
name char(30) NOT NULL, 
PRIMARY KEY (`id`));
Query OK, 0 rows affected (0.29 sec)

CREATE TABLE animal_count (animals int);

INSERT INTO animal_count (animals) VALUES(0);

Vogliamo incrementare un contatore ogni volta che un animale viene aggiunto. Ecco il trigger necessario:

MariaDB [test]> CREATE TRIGGER increment_animal 
AFTER INSERT ON animals 
FOR EACH ROW 
UPDATE animal_count SET animal_count.animals = animal_count.animals+1;

Il trigger ha:

  • un nome (in questo caso increment_animal)
  • una tempistica (in questo caso after, dopo l'evento specificato)
  • un evento (una INSERT)
  • una tabella al quale è associato (animals)
  • un insieme di istruzioni da eseguire (in questo caso una sola istruzione UPDATE)

AFTER INSERT specifica che il trigger deve essere eseguito dopo una INSERT. Il trigger può anche essere impostato per agire prima, e l'istruzione che aziona il trigger può anche essere una DELETE o una UPDATE.

Ora, se inseriamo un record nella tabella animals, il trigger verrà eseguito, incrementando la tabella animal_count;

MariaDB [test]> SELECT * FROM animal_count;
+---------+
| animals |
+---------+
|       0 |
+---------+

MariaDB [test]> INSERT INTO animals (name) VALUES('aardvark');
MariaDB [test]> INSERT INTO animals (name) VALUES('baboon');

MariaDB [test]> SELECT * FROM animal_count;
+---------+
| animals |
+---------+
|       2 |
+---------+

Per ulteriori dettagli sulla sintassi, si veda CREATE TRIGGER.

Eliminare i trigger

Per eliminare un trigger, si usa l'istruzione DROP TRIGGER. I trigger inoltre vengono eliminati se si elimina la tabella alla quale sono associati.

MariaDB [test]> DROP TRIGGER increment_animal; 

Trigger più complessi

I trigger possono consistere di più istruzioni racchiuse tra BEGIN e END. Se si stanno inserendo queste istruzioni dalla riga di comando, è necessario impostare temporaneamente un nuovo delimitatore, per poter utilizzare i punto e virgola come delimitatore per le istruzioni che compongono il trigger.

MariaDB [test]> DROP TABLE animals;

MariaDB [test]> UPDATE animal_count SET animals=0;

MariaDB [test]> CREATE TABLE animals (id mediumint(9) NOT NULL AUTO_INCREMENT, 
name char(30) NOT NULL, 
PRIMARY KEY (`id`)) 
ENGINE=InnoDB;

MariaDB [test]> DELIMITER //
CREATE TRIGGER the_mooses_are_loose
AFTER INSERT ON animals
FOR EACH ROW
BEGIN
 IF NEW.name = 'Moose' THEN
  UPDATE animal_count SET animal_count.animals = animal_count.animals+100;
 ELSE 
  UPDATE animal_count SET animal_count.animals = animal_count.animals+1;
 END IF;
END; //

MariaDB [test]> DELIMITER ;

MariaDB [test]> INSERT INTO animals (name) VALUES('Aardvark');

MariaDB [test]> SELECT * FROM animal_count;
+---------+
| animals |
+---------+
|       1 |
+---------+

MariaDB [test]> INSERT INTO animals (name) VALUES('Moose');

MariaDB [test]> SELECT * FROM animal_count;
+---------+
| animals |
+---------+
|     101 |
+---------+
1 row in set (0.00 sec)

Errori nei trigger

Se un trigger contiene un errore e lo Storage Engine è transazionale, il trigger non si esegue, e non viene eseguita nemmeno l'istruzione originale. Se l'Engine non è transazionale, il trigger non si esegue, ma l'istruzione originale sì.

Qui di seguito abbandoniamo gli esempi precedenti, e ricreiamo il trigger con un errore, cioè un campo che non esiste, utilizzando prima lo Storage Engine predefinito InnoDB, che è transazionale, e poi usando MyISAM, uno Storage Engine non transazionale.

MariaDB [test]> DROP TABLE animals;

MariaDB [test]> CREATE TABLE animals (id mediumint(9) NOT NULL AUTO_INCREMENT, 
name char(30) NOT NULL, 
PRIMARY KEY (`id`)) 
ENGINE=InnoDB;

MariaDB [test]> CREATE TRIGGER increment_animal 
AFTER INSERT ON animals 
FOR EACH ROW 
UPDATE animal_count SET animal_count.id = animal_count_id+1;

MariaDB [test]> INSERT INTO animals (name) VALUES('aardvark');
ERROR 1054 (42S22): Unknown column 'animal_count.id' in 'field list'

MariaDB [test]> SELECT * FROM animals;
Empty set (0.00 sec)

E ora la stessa procedura, ma su una tabella MyISAM.

MariaDB [test]> DROP TABLE animals;

MariaDB [test]> CREATE TABLE animals (id mediumint(9) NOT NULL AUTO_INCREMENT, 
name char(30) NOT NULL, 
PRIMARY KEY (`id`)) 
ENGINE=MyISAM;

MariaDB [test]> CREATE TRIGGER increment_animal 
AFTER INSERT ON animals 
FOR EACH ROW 
UPDATE animal_count SET animal_count.id = animal_count_id+1;

MariaDB [test]> INSERT INTO animals (name) VALUES('aardvark');
ERROR 1054 (42S22): Unknown column 'animal_count.id' in 'field list'

MariaDB [test]> SELECT * FROM animals;
+----+----------+
| id | name     |
+----+----------+
|  1 | aardvark |
+----+----------+
1 row in set (0.00 sec)

Commenti

Sto caricando i commenti......