Curso de MariaDB Desde la Consola/Triggers

De WikiCabal
Saltar a: navegación, buscar

Triggers y Events

A trigger, as its name suggests, is a set of statements that run, or are triggered, when an event occurs on a table.

Sintaxis

CREATE TRIGGER <Trigger name>
{BEFORE | AFTER} <trigger event> ON <Table name>
[ REFERENCING <old or new values alias list> ]
<triggered action>

   <trigger event> ::=
   INSERT |
   DELETE |
   UPDATE [ OF <trigger Column list> ]

      <trigger Column list> ::= <Column name> [ {,<Column name>} ... ]

   <old or new values alias list> ::=
   <old or new values alias>...

      <old or new values alias> ::=
      OLD [ ROW ] [ AS ] old values <Correlation name> |
      NEW [ ROW ] [ AS ] new values <Correlation name> |
      OLD TABLE [ AS ] <old values Table alias> |
      NEW TABLE [ AS ] <new values Table alias>

         <old values Table alias> ::= <identifier>

         <new values Table alias> ::= <identifier>

   <triggered action> ::=
   [ FOR EACH {ROW | STATEMENT} ] [ WHEN (search condition) ]
      <triggered SQL statement>

      <triggered SQL statement> ::=
      SQL statement |
      BEGIN ATOMIC {SQL statement;}... END

Descripción

CREATE TRIGGER define un nuevo Trigger.

El <Trigger name> identifica el Trigger y el Schema al que pertenece. Típico <Trigger name>s incluye el evento Trigger, por ejemplo:

 "Empleado_Update" o "After_Delete_From_Empleado". 

Un <Trigger name> que incluye un calificador de <nombre de schema> explícito pertenece al schema nombrado. Un <Trigger name> que no incluye un calificador de <nombre de schema> explícito pertenece al schema predeterminado de sesión de SQL. El <Trigger name> debe ser único (para todos los Triggers) dentro del schema que lo posee.

Si CREATE TRIGGER es parte de una sentencia CREATE SCHEMA, el <Trigger name>, si está explícitamente calificado, debe incluir el <nombre de schema> del schema que se está creando; Es decir, no es posible crear un Trigger perteneciente a un schema diferente desde CREATE SCHEMA. Por ejemplo, esta sentencia de SQL no devolverá un error porque el <Nombre del trigger> incluirá por defecto el <Nombre del schema> que califica:

CREATE SCHEMA bob
  CREATE TABLE Table_1 (column_1 SMALLINT)
  CREATE TRIGGER Trigger_1 AFTER DELETE ON Table_1
      INSERT INTO Log_table VALUES ('deleted from Table_1');
-- creates a Trigger called BOB.TRIGGER_1 in Schema BOB

La instrucción SQL siguiente no devolverá un error ya sea porque el <nombre de trigger> incluye explícitamente un <nombre de schema> que califica que coincide con el nombre del schema que se está creando:

CREATE SCHEMA bob
  CREATE TABLE bob.Table_1 (column_1 SMALLINT)
  CREATE TRIGGER bob.Trigger_1 AFTER DELETE ON Table_1
      INSERT INTO Log_table VALUES ('deleted from Table_1');
-- creates a Trigger called BOB.TRIGGER_1 in Schema BOB

Sin embargo, esta sentencia SQL devolverá un error porque el <nombre del trigger> incluye explícitamente un <nombre de schema> que es diferente al nombre del schema que se está creando:

CREATE SCHEMA bob
  CREATE TABLE bob.Table_1 (column_1 SMALLINT)
  CREATE TRIGGER sam.Trigger_1 AFTER DELETE ON bob.Table_1
      INSERT INTO Log_table VALUES ('deleted from Table_1');
-- tries to create a Trigger belonging to Schema SAM inside Schema BOB; illegal syntax

Si CREATE TRIGGER se ejecuta como una instrucción SQL autónoma, el <AuthorizationID> actual debe ser el propietario del schema al que pertenece este nuevo trigger o el propietario del Schema debe ser un Role que el actual <AuthorizationID> pueda utilizar. Es decir, sólo el propietario de un schema puede crear triggers para ese schema.

Las partes principales de la sentencia CREATE TRIGGER son su tabla, su evento (la descripción de la instrucción de cambio de datos de SQL que activa el trigger) y su acción (las sentencias de SQL que deben ejecutar el trigger).

Cláusula ON

La cláusula ON de la instrucción CREATE TRIGGER nombra la Tabla de triggers: la tabla Base que, cuando se cambia, puede causar que el trigger actúe. La tabla debe pertenecer al mismo schema al que pertenece el trigger y el <AuthorizationID> actual debe tener el privilegio TRIGGER en esa tabla. (No se necesita un privilegio para "utilizar" un trigger, los activadores se activarán cada vez que ejecute la instrucción de cambio de datos SQL apropiada en la tabla, independientemente de si desea o no).

Tiempo de acción del disparador

El tiempo de acción del trigger define cuándo desea que se ejecute la acción del trigger: puede ser BEFORE p AFTER. El tiempo de acción de trigger debe ser ANTES si desea que la acción de trigger ocurra antes del evento de trigger. Debe ser después de si desea que la acción de trigger se produzca después del evento de trigger .

Evento de disparo

El evento Trigger define la sentencia de cambio de datos SQL cuya ejecución activará el trigger: puede ser INSERT, DELETE o UPDATE. En el caso de UPDATE sólo, puede agregar una subcláusula opcional que enumera las columnas de trigger: las columnas en las que UPDATE activará el trigger (UPDATE en columnas que no están en la lista no activará el trigger). La lista de columnas nombra algunas o todas las columnas de la tabla de trigger (cada una puede aparecer en la lista sólo una vez). Si omite esta subcláusula opcional, el efecto es como si incluyera una cláusula OF que nombra cada columna de la tabla del trigger.

Cláusula REFERENCING

La cláusula REFERENCING opcional de la instrucción CREATE TRIGGER define una lista de uno a cuatro nombres únicos o alias: un nombre para la fila antigua actuada por el trigger y/o un nombre para la nueva fila actuada por el trigger y/o un nombre para la tabla antigua actuada por el trigger y/o un nombre para la nueva Tabla actuada por el trigger (cada uno se puede especificar una vez). El <keyword> AS en cada opción de alias es ruido y puede omitirse. Si no se especifica ROW ni TABLE, el valor por defecto es ROW - por ejemplo, estas cuatro instrucciones SQL son equivalentes:

CREATE TRIGGER Trigger_1
  AFTER UPDATE ON Table_1 REFERENCING OLD ROW AS old_row_name
      FOR EACH ROW INSERT INTO Log_table VALUES ('updated Table_1');

CREATE TRIGGER Trigger_1
  AFTER UPDATE ON Table_1 REFERENCING OLD ROW old_row_name
      FOR EACH ROW INSERT INTO Log_table VALUES ('updated Table_1');

CREATE TRIGGER Trigger_1
  AFTER UPDATE ON Table_1 REFERENCING OLD AS old_row_name
      FOR EACH ROW INSERT INTO Log_table VALUES ('updated Table_1');

CREATE TRIGGER Trigger_1
  AFTER UPDATE ON Table_1 REFERENCING OLD old_row_name
      FOR EACH ROW INSERT INTO Log_table VALUES ('updated Table_1');

Su definición de trigger debe incluir una cláusula REFERENCING si la acción truigger contiene referencias al <Nombre de la tabla> del trigger o cualquiera de sus <Nombre de columna>. Los valores OLD son los valores antes del evento UPDATE / DELETE Trigger (OLD ROW y OLD TABLE no están permitidos si el evento Trigger es INSERT) y los valores NEW son los valores después del evento UPDATE / INSERT Trigger (NEW ROW y NEW TABLE No está permitido si el evento de trigger es DELETE). Si el tiempo de acción de trigger es ANTES, una cláusula de REFERENCIA no puede especificar OLD TABLE o NEW TABLE.

Cada evento Trigger tiene su propio "contexto de ejecución": incluye los valores antiguos de fila y/o los nuevos valores de fila de la Tabla de triggers. Si el evento de trigger es INSERT, entonces no hay valores de fila antiguos ya que ninguna fila existente de una tabla se ve afectada por INSERT. Si el evento de trigger es DELETE, no hay nuevos valores de fila ya que la acción de DELETE es quitar filas de una tabla. Si el evento Trigger es UPDATE, hay tres versiones de fila:

   1. La fila real de datos en la Tabla del trigger.

   2. La copia "vieja fila" de la fila real - a menudo igual que [1], pero si hay dos eventos 
      distintos de ACTUALIZACIÓN entonces puede haber una diferencia entre [1] y [2]. 
      Llamaremos a esto la "vieja fila" de ahora en adelante. El conjunto de todas las filas 
      antiguas es la "tabla antigua".
   
   3. La copia "new row values" de la fila real: contiene lo que el DBMS propone cambiar la 
      fila real una vez que se completa la ejecución de la instrucción UPDATE. Llamaremos a 
      esto la "nueva fila" de ahora en adelante. El conjunto de todas las nuevas filas es 
      la "nueva tabla". (Nota: Incluso con un BEFORE Trigger, los "nuevos valores de fila" 
      son conocidos por el DBMS.)

El contexto de ejecución de un Trigger es importante (de hecho, es obligatorio) si va a referirse a la Tabla de triggers en las declaraciones de acción del trigger. Normalmente sería incorrecto referirse a la Columna COLUMN_1 de la Tabla TABLE_1 con su <Referencia de Columna>, TABLE_1.COLUMN_1, ya que la <Referencia de Columna> se refiere a esa Columna en la copia de la Tabla Base actual. Lo que realmente necesita hacer referencia es la fila antigua o la nueva fila. La cláusula REFERENCING de la instrucción CREATE TRIGGER permite especificar qué nombres de contexto se usan para referirse a OLD ROW o NEW ROW en la acción trigger.

El contexto de ejecución es "atómico" en el sentido usual de SQL de la palabra: si cualquier instrucción de acción falla, entonces todas las instrucciones de acción fallan y también lo hace la declaración que causó la activación del trigger: su DBMS devolverá el error SQLSTATE 09000 "triggered action exception". En otras palabras, la fila antigua y la nueva fila se destruyen simplemente y quedan con la misma cosa que empezó: la fila real.

Acción de trigger

La acción trigger define las sentencias SQL que desea que el trigger ejecute cuando se active y tiene tres partes: la granularidad de la acción, la acción cuando la condición y el cuerpo de la acción.

Acción Granularidad

La cláusula opcional FOR EACH de la sentencia CREATE TRIGGER define la granularidad de la acción: puede ser FOR EACH STATEMENT (la predeterminada) o FOR EACH ROW. La granularidad de acción le indica a su DBMS cuán grande es el campo de acción. Por ejemplo, suponga que crea un trigger para "AFTER UPDATE OF column_1 ON Employees" y, a continuación, haga lo siguiente:

 UPDATE Employees SET column_1 = 5;

Suponga que la tabla EMPLOYEES tiene 1000 filas. Si la granularidad de acción es FOR EACH STATEMENT, la acción de trigger se producirá una vez (sólo para la sentencia). Si la granularidad de acción es FOR EACH ROW, la acción Trigger se producirá 1000 veces (una vez para cada fila de la tabla de trigger). Como se indicó anteriormente, el valor predeterminado es FOR EACH STATEMENT, pero la granularidad de "row" es más común. De hecho, si su definición de trigger contiene una cláusula REFERENCING que incluye OLD ROW o NEW ROW, también debe incluir una cláusula de granularidad de acción de FOR EACH ROW

Acción WHEN Condición

La cláusula WHEN opcional de la sentencia CREATE TRIGGER define la acción trigger cuando condición: puede ser cualquier condición de búsqueda entre paréntesis. Cuando se activa el trigger, si la condición de búsqueda es TRUE, la acción de trigger ocurrirá, si la condición de búsqueda es FALSE, la acción de trigger no se producirá y si la condición de búsqueda es UNKNOWN, aparentemente no se producirá la acción de trigger. El documento estándar no está claro sobre este punto. Si omite la cláusula WHEN de una definición de trigger, la acción trigger se producirá tan pronto como se active el trigger.

Normalmente, agregaría una cláusula WHEN a la definición de trigger si la definición de evento de trigger es demasiado general para sus propósitos. Por ejemplo, el evento de trigger podría ser "UPDATE Empleados", pero la acción de trigger debería ocurrir solamente "CUANDO el salario > 1000.00". Tal especificidad sólo tiene sentido si la granularidad de acción es FOR EACH ROW.

Acción Body

El cuerpo de acción de la instrucción CREATE TRIGGER define la acción de trigger en sí: la instrucción SQL que desea que su DBMS ejecute cuando se activa el trigger. El cuerpo de acción puede ser una sentencia SQL única o puede ser una serie de instrucciones SQL, delimitadas por punto y coma, con una subcláusula BEGIN ATOMIC ... END. Aquí hay dos ejemplos de cuerpos de acción de (el primero muestra un cuerpo de acción usando una sola sentencia de SQL y el segundo muestra un cuerpo de acción que muestra varias sentencias de SQL):

... UPDATE Table_1

... BEGIN ATOMIC
      DELETE FROM Table_1;
      DELETE FROM Table_2;
      DELETE FROM Table_3;
  END

La acción trigger no puede contener una variable de host o una referencia de parámetro de SQL ni puede contener una sentencia de SQL activada que sea una sentencia de transacción de SQL, una sentencia de conexión de SQL, una sentencia de SQL Schema o una sentencia de sesión SQL Sin embargo, una gran variedad de sentencias SQL son legales dentro del cuerpo del trigger.

Si el tiempo de acción de trigger es ANTES, la acción de trigger puede incluir estas sentencias SQL: DECLARE TABLE, DECLARE CURSOR, OPEN, CLOSE, FETCH, SELECT (para una sola fila solamente), FREE LOCATOR, HOLD LOCATOR, CALL, RETURN y GET DIAGNOSTICS. También puede nombrar una rutina invocada por SQL, siempre y cuando esa rutina no sea una que posiblemente modifique datos SQL . Si el tiempo de acción del trigger es AFTER, la acción Trigger puede incluir todas las sentencias SQL permitidas para BEFORE Triggers, además de: INSERT, UPDATE y DELETE. También puede nombrar cualquier rutina invocada por SQL.

De las instrucciones SQL disponibles para una acción de trigger, OPEN, FETCH, CLOSE, SELECT de una

sola fila y GET DIAGNOSTICS no son muy útiles porque está prohibido incluir variables y parámetros 

de host dentro del cuerpo de acción de una definición de trigger. INSERT, UPDATE y DELETE son mucho más útiles; A menudo un cuerpo de acción de trigger consiste en sólo una de dichas sentencias de cambio de datos de SQL. (Recuerda, sin embargo, que no puedes usarlos con un BEFORE Trigger.) Las rutinas invocadas por SQL también son útiles. En efecto, un procedimiento en su programa de lenguaje de host puede ser llamado por un Trigger.

Si desea restringir su código a Core SQL, no utilice la instrucción CREATE TRIGGER.

Events

El evento puede ser INSERT, UPDATE o DELETE. El trigger se puede ejecutar ANTES o DESPUÉS del evento. Cada tabla sólo puede tener un trigger definido para cada combinación de EVENT/TIMING: por ejemplo, una tabla sólo puede tener un trigger BEFORE INSERT

Los LOAD DATA INFILE y LOAD XML instrucciones Invocar triggers INSERT para cada fila que se está insertando. La instrucción REPLACE se ejecuta con el siguiente flujo de trabajo

  • BEFORE INSERT;
  • BEFORE DELETE (Sólo si está eliminando una file);
  • AFTER DELETE (Sólo si está eliminando una file);
  • AFTER INSERT.

El INSERT ... ON DUPLICATE KEY UPDATE instrucción, cuando ya existe una fila, sigue el siguiente flujo de trabajo:

  • BEFORE INSERT;
  • BEFORE UPDATE;
  • AFTER UPDATE.

De lo contrario, funciona como una instrucción INSERT normal. Tenga en cuenta que TRUNCATE TABLE no activa ningún trigger.

Triggers y Errores

Con motores de almacenamiento no transaccionales, si una instrucción BEFORE produce un error, la sentencia no se ejecutará. Las sentencias que afectan a varias filas fallarán antes de insertar la fila actual.

Con los motores transaccionales, los triggers se ejecutan en la misma transacción que la sentencia que los invocó.

Si se emite una advertencia con la sentencia SIGNAL o RESIGNAL (es decir, un error con un SQLSTATE que comienza con '01'), se tratará como un error.

Crear un Trigger

Aquí hay un ejemplo sencillo para demostrar un trigger en acción. Utilizando estas dos tablas como ejemplo:

CREATE TABLE Animales( ID mediumint(9) NOT NULL AUTO_INCREMENT, 
                       Nombre char(30) NOT NULL, 
                       PRIMARY KEY (`ID`));

Query OK, 0 rows affected (0.39 sec)

CREATE TABLE ConteoDeAnimales( Animales int);

Query OK, 0 rows affected (0.31 sec)

INSERT INTO ConteoDeAnimales( Animales) VALUES( 0 );

Query OK, 1 row affected (0.05 sec)

Queremos incrementar un contador cada vez que se añade un nuevo animal. Esto es lo que el trigger se verá así:

CREATE TRIGGER IncrementoConteoDeAnimales
  AFTER INSERT ON Animales
  FOR EACH ROW 
  UPDATE ConteoDeAnimales SET ConteoDeAnimales.Animales = ConteoDeAnimales.Animales + 1;

Query OK, 0 rows affected (0.10 sec)

Este trigger tiene:

  • Un nombre (en este caso: IncrementoConteoDeAnimales)
  • Un trigger tiempo (en este cso: after el evento especificado)
  • Un trigger evento (un INSERT)
  • Una tabla con la que está asociada: Animales)
  • Instrucciones para ejecutar (En este caso solo un UPDATE instrucción)

AFTER INSERT especifica que el trigger ejecutará después de un INSERT. El trigger también podría configurarse para ejecutarse antes, y la sentencia que provoca el trigger podría ser una DELETE o UPDATE también.

AFTER INSERT especifica que el trigger ejecutará después de un INSERT. El trigger también podría configurarse para ejecutarse antes, y la sentencia que provoca el trigger podría ser una DELETE o UPDATE también.

Ahora, si insertamos un registro en la tabla Animales, el trigger se ejecutará, incrementando la tabla ConteoDeAnimales;

SELECT * FROM ConteoDeAnimales;
+----------+
| Animales |
+----------+
|        0 |
+----------+
1 row in set (0.00 sec)

INSERT INTO Animales (Nombre) VALUES('aardvark');
Query OK, 1 row affected (0.09 sec)

INSERT INTO Animales (Nombre) VALUES('baboon');
Query OK, 1 row affected (0.10 sec)

MariaDB [MiPrueba1]> SELECT * FROM ConteoDeAnimales;
+----------+
| Animales |
+----------+
|        2 |
+----------+
1 row in set (0.00 sec)

Triggers metadata

The Information Schema TRIGGERS Table stores information about triggers. The SHOW TRIGGERS statement returns similar information. The SHOW CREATE TRIGGER statement returns a CREATE TRIGGER statement that creates the given trigger

MariaDB [MiPrueba1]> show triggers \G;
*************************** 1. row ***************************
             Trigger: IncrementoConteoDeAnimales
               Event: INSERT
               Table: Animales
           Statement: UPDATE ConteoDeAnimales SET ConteoDeAnimales.Animales = ConteoDeAnimales.Animales + 1
              Timing: AFTER
             Created: NULL
            sql_mode: 
             Definer: root@localhost
character_set_client: utf8
collation_connection: utf8_general_ci
  Database Collation: utf8_unicode_ci
1 row in set (0.00 sec)

MariaDB [MiPrueba1]> SHOW CREATE TRIGGER IncrementoConteoDeAnimales \G;
*************************** 1. row ***************************
               Trigger: IncrementoConteoDeAnimales
              sql_mode: 
SQL Original Statement: CREATE DEFINER=`root`@`localhost` TRIGGER IncrementoConteoDeAnimales
  AFTER INSERT ON Animales
  FOR EACH ROW 
  UPDATE ConteoDeAnimales SET ConteoDeAnimales.Animales = ConteoDeAnimales.Animales + 1
  character_set_client: utf8
  collation_connection: utf8_general_ci
    Database Collation: utf8_unicode_ci
1 row in set (0.00 sec)

Borrar un Trigger

Para borrar un trigger, utilice la declaración DROP TRIGGER. Los triggers también se eliminan si la tabla con la que están asociados también se ha eliminado.

DROP TRIGGER IncrementoConteoDeAnimales;
Query OK, 0 rows affected (0.01 sec)

More complex triggers

Los triggers pueden consistir en varias sentencias incluidas por un BEGIN y END. Si está ingresando varias sentencias en la línea de comandos, deseará establecer temporalmente un nuevo delimitador para que pueda utilizar un punto y coma para delimitar las sentencias dentro del trigger.

DROP TABLE Animales;
Query OK, 0 rows affected (0.15 sec)

UPDATE ConteoDeAnimales SET Animales = 0;
Query OK, 1 row affected (0.08 sec)
Rows matched: 1  Changed: 1  Warnings: 0

CREATE TABLE Animales( ID mediumint(9) NOT NULL AUTO_INCREMENT, 
                       Nombre char(30) NOT NULL, 
                       PRIMARY KEY (`ID`)) 
                       ENGINE=InnoDB;
Query OK, 0 rows affected (0.37 sec)

DELIMITER //

CREATE TRIGGER LosRatonesInvaden
  AFTER INSERT ON Animales
  FOR EACH ROW
  BEGIN
    IF NEW.Nombre = 'Mouse' THEN
      UPDATE ConteoDeAnimales SET ConteoDeAnimales.Animales = ConteoDeAnimales.Animales + 100;
    ELSE 
      UPDATE ConteoDeAnimales SET ConteoDeAnimales.Animales = ConteoDeAnimales.Animales + 1;
    END IF;
  END; //
Query OK, 0 rows affected (0.08 sec)

DELIMITER ;

SELECT * FROM ConteoDeAnimales;
+----------+
| Animales |
+----------+
|        0 |
+----------+
1 row in set (0.00 sec)

INSERT INTO Animales (Nombre) VALUES('Aardvark');
Query OK, 1 row affected (0.05 sec)

SELECT * FROM ConteoDeAnimales;
+----------+
| Animales |
+----------+
|        1 |
+----------+
1 row in set (0.00 sec)

INSERT INTO Animales (Nombre) VALUES('Mouse');
Query OK, 1 row affected (0.12 sec)

SELECT * FROM ConteoDeAnimales;
+----------+
| Animales |
+----------+
|      101 |
+----------+
1 row in set (0.00 sec)

Errores de Trigger

Si un trigger contiene un error y el motor es transaccional, o el es un BEFORE trigger, no se ejecutará y evitará que se ejecute la sentencia original. Si el motor no es transaccional y es un AFTER trigger, el trigger no se ejecutará, pero la instrucción original lo hará.

Aquí, eliminaremos los ejemplos anteriores y, a continuación, volveremos a crear el trigger con un error, un campo que no existe, usando el InnoDB predeterminado , Un motor transaccional y, de nuevo, utilizando MyISAM un motor no transaccional.

DROP TABLE Animales;

CREATE TABLE Animales (ID mediumint(9) NOT NULL AUTO_INCREMENT, 
nombre char(30) NOT NULL, 
PRIMARY KEY (`ID`)) 
ENGINE=InnoDB;

CREATE TRIGGER  IncrementoConteoDeAnimales
AFTER INSERT ON Animales 
FOR EACH ROW 
UPDATE ConteoDeAnimales SET ConteoDeAnimales.ID = ConteoDeAnimales_id+1;

INSERT INTO Animales (nombre) VALUES( 'aardvark' );

ERROR 1054 (42S22): Unknown column 'ConteoDeAnimales.ID' in 'field list'

SELECT * FROM animals;
Empty set (0.00 sec)

Y ahora el procedimiento idéntico, pero con una tabla MyISAM

DROP TABLE Animales;

CREATE TABLE Animales (ID mediumint(9) NOT NULL AUTO_INCREMENT, 
name char(30) NOT NULL, 
PRIMARY KEY (`ID`)) 
ENGINE=MyISAM;

CREATE TRIGGER  IncrementoConteoDeAnimales
AFTER INSERT ON Animales 
FOR EACH ROW 
UPDATE ConteoDeAnimales SET ConteoDeAnimales.ID = ConteoDeAnimales_id+1;

INSERT INTO Animales (name) VALUES('aardvark');


ERROR 1054 (42S22): Unknown column 'animal_count.id' in 'field list'


SELECT * FROM Animales;
+----+----------+
| id | name     |
+----+----------+
|  1 | aardvark |
+----+----------+

El ejemplo siguiente muestra cómo utilizar un trigger para validar datos. La sentencia SIGNAL se utiliza para producir un error intencionalmente si el campo de correo electrónico no es un correo electrónico válido. Como muestra el ejemplo, en ese caso la nueva fila no se inserta (porque es un BEFORE trigger).

CREATE TABLE Usuario (
	ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
	Nombre CHAR(20),
	Apellido CHAR(20),
	EMail CHAR(100)
)
	ENGINE = MyISAM;

DELIMITER //
CREATE TRIGGER Bi_Usuario
  BEFORE INSERT ON Usuario
  FOR EACH ROW
BEGIN
  IF NEW.EMail NOT LIKE '_%@_%.__%' THEN
    SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'EMail campo no está valido';
  END IF;
END; //
DELIMITER ;

INSERT INTO Usuario (Nombre, Apellido, EMail) VALUES ('Juan', 'Valdez', 'JuanValdez.AlgunLugar.net');


ERROR 1644 (45000): EMail campo no está valido

SELECT * FROM Usuario; Empty set (0.00 sec)