Otra de las nuevas características incluidas en MySQL, además de los procedimientos almacenados, son los triggers, que traducido sería algo así como disparadores, son oyentes, que se mantienen a la escucha de los eventos que puedan producirse en una tabla (insert , update y delete) y ejecutan un código antes (before) o después (after) de que se produzca este evento.

Con los triggers podemos hacer cosas tan interesantes como mantener un log de que usuarios hace modificaciones en una tabla, que usuarios borran registros, o insertan, o lo que se te ocurra.

Para referenciar las columnas de antes y después de que el vento se haya disparado, se usan las palabras clave OLD y NEW. Con la sentencia insert solo se permite NEW, con update se permiten ambas y con delete solo OLD.

Sintaxis necesaria para crear un trigger

CREATE TRIGGER <nombre>
    {BEFORE|AFTER}
    {INSERT|UPDATE|DELETE}
    ON
<tablename>
    FOR EACH ROW
    BEGIN
    <sentenciasSQL>
    END;

Para poner nombre a los triggers es conveniente seguir una convención que hará más fácil identificar sobre que evento y tabla actúa el trigger. Esta sería una buena forma de nombrar nuestros triggers:

NombreTabla + “_” + abreviatura_tipo_tigger

Por lo tanto para nombrar un triger que se ejecuta sobre la tabla T1 después de un update lo haríamos de la siguiente forma si seguimos esta convención:

“T1_BU”

Esto puede ser útil, pero no es necesario, puedes poner el nombre que quieras a tu trigger.

Para crear triggers en una tabla es necesario hacerlo desde un usuario con permisos para ello. Para dar permiso a un usuario en una tabla para crear un trigger lo haríamos de la siguiente forma:

GRANT CREATE TRIGGER ON nombreTabla TO Usuario

Vamos a ver un ejemplo sencillo:

Creamos la tabla miTabla

CREATE TABLE miTabla( id int , nombre varchar(50) );

Y después creamos un trigger que va a crear una variable global con el nombre antiguo antes de ejecutar el update y otra con el nombre nuevo que habrá después de ejecutar el update.

delimiter //
CREATE TRIGGER miTabla_bu before UPDATE
ON miTabla
FOR each row
begin
    SET @nombreViejo = OLD.nombre;
    SET @nombreNuevo = NEW.nombre;
end//

Vamos a ver otro tigger :

CREATE TRIGGER miTabla_bi
before INSERT ON miTabla
FOR each row
begin
    SET @x = 'Trigger activado';
    SET NEW.nombre = ‘Valor introducido desde el TRIGGER’;
end//

En esta ocasión, cada vez que se haga un insert sobre la tabla miTabla, se creará una variable global con el valor ‘Trigger activado’ y modificará el valor que se insertará en la columna nombre, por lo que siempre se insertará el valor ‘Valor introducido desde el trigger’.

Si lo que queremos es mantener el control de una tabla para ver quien la modifica y a que hora, podemos crear una tabla donde iremos anotando quien hace cada modificación y anotar los cambios.

Creamos la tabla auxiliar

CREATE TABLE controlMiTabla
(
   id int NOT NULL AUTO_INCREMENT,
   id_registro int,
   anterior_nombre varchar(50),
   nuevo_nombre varchar(50),
   usuario varchar(40),
   modificado datetime,
   PRIMARY KEY(id)
) ENGINE = InnoDB;

Y ahora vamos a crear un trigger que se encargue de llevar un log de quien actualiza la tabla, que valores modifica y a que hora:

delimiter //
CREATE TRIGGER MiTabla_BU after UPDATE ON miTabla
   FOR each row
    begin
         INSERT INTO controlMiTabla (id_registro, anterior_nombre , nuevo_nombre, usuario  , modificado ) VALUES(OLD.id , OLD.nombre , NEW.nombre, CURRENT_USER(), NOW() );
    end//

Y ya tenemos nuestro trigger creado, con el cual llevaremos el control de la tabla.

Esto es recomendable hacerlo solo en las tablas de importancia critica, ya que si no nuestra base de datos crecerá de forma innecesaria.

Compartir:
  • del.icio.us
  • BarraPunto
  • Bitacoras.com
  • Facebook
  • Google Bookmarks
  • Meneame
  • Netvibes
  • Technorati
  • FriendFeed
  • Twitter
  • HelloTxt


Comentarios

  1. 1
    Jesus Lopez
    18 de enero del 2009 a las 12:43 pm

    Gracias por ese aporte sencillo pero muy entendible.
    Saludos

  2. 2
    Ricoski
    18 de febrero del 2009 a las 5:26 am

    Buen aporte sobre los trigger’s. Agradecimientos.

  3. 3
    RhapsodyOfFire
    21 de febrero del 2009 a las 5:38 pm

    Gracias a este tutorial aprendi el uso de triggers.
    Saludos

  4. 4
    daniel
    5 de marzo del 2009 a las 6:02 pm

    Excelente tutorial! Gracias

  5. 5
    Ramón
    10 de marzo del 2009 a las 7:08 am

    Excelente, muchas gracias, finalmente entendi como funcionan los triggers.

  6. 6
    Diego
    12 de marzo del 2009 a las 5:48 am

    Hola, mira ejecuto el trigger, pero me arroja error, dice que se requiere privilegio de super para ejecutar dicha accion, podrias ayudarme

  7. 7
    supercharly
    18 de marzo del 2009 a las 6:02 pm

    informacion clara y concisa, por fin un poco de oxigeno en la web, se agradece el tiempo para los novatos

  8. 8
    Jessica
    23 de marzo del 2009 a las 2:24 pm

    Hola buen día.. muy buena la información… ya salió todo bien. Mepregunto si tienes algún ejemplo de triggers anidados.
    También me pregunto si tienes algun ejemplo de triggers en Workbench.
    gracias por todo

  9. 9
    Dey
    14 de mayo del 2009 a las 10:09 am

    Buen aporte compañero se agardec de antemano espero me sirva ya que en un aporte valioso

  10. 10
    LGDV
    15 de mayo del 2009 a las 1:45 pm

    Hola, que tal.
    Cuando realizo el segundo script del ejemplo de arriba me aparece esto:
    delimiter //
    CREATE TRIGGER miTabla_bu before UPDATE
    ON miTabla
    FOR each row
    begin
    SET @nombreViejo = OLD.nombre;
    SET @nombreNuevo = NEW.nombre;
    end//

    me aparece el siguiente error:

    Parece haber un error en su consulta de SQL. La salida generada por el servidor de MySQL, de existir, aparece abajo, en cuyo caso puede ayudar a diagnosticar el problema.

    ERROR: Signo de puntuación desconocido @ 11
    STR: //
    SQL: delimiter //
    CREATE TRIGGER miTabla_bu before UPDATE
    ON miTabla
    FOR each row
    begin
    SET @nombreViejo = OLD.nombre;delimiter //
    CREATE TRIGGER miTabla_bu before UPDATE
    ON miTabla
    FOR each row
    begin
    SET @nombreViejo = OLD.nombre;delimiter //
    CREATE TRIGGER miTabla_bu before UPDATE
    ON miTabla
    FOR each row
    begin
    SET @nombreViejo = OLD.nombre;delimiter //
    CREATE TRIGGER miTabla_bu before UPDATE
    ON miTabla
    FOR each row
    begin
    SET @nombreViejo = OLD.nombre;

    consulta SQL:

    delimiter // CREATE TRIGGER miTabla_bu before UPDATE ON miTabla FOR each row begin SET @nombreViejo = OLD.nombre;

    MySQL ha dicho: Documentación
    #1064 – You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘delimiter //
    CREATE TRIGGER miTabla_bu before UPDATE
    ON miTabla
    FOR each row
    ‘ at line 1

    quisiera un poco de ayuda por favor Gracias

  11. 11
    Lucas
    23 de mayo del 2009 a las 3:17 pm

    Muy buen aporte, me sirvio muchisimo, gracias

  12. 12
    Fernando Pérez
    23 de noviembre del 2009 a las 7:31 am

    Muchas gracias por este post estoy muy contento, llevaba 2 años buscando temas así todo sobre triggers, procedure y funtions y otras cosas más.!!!!

    Este post me sirvio bastante no te imaginas

  13. 13
    alejo
    3 de diciembre del 2009 a las 5:32 pm

    muchas gracias por el aporte, me ayudo a recordar este tema que por poca practica había olvidado

  14. 14
    ITSA
    8 de diciembre del 2009 a las 8:27 am

    HOLA ING. DE AQUI SACO LO DEL EXAMEN MUY BIEN EXPLICADO SUERTE

  15. 15
    jesus
    15 de diciembre del 2009 a las 7:47 am

    gran aporte
    me sirvio de algo que
    pero toda via no me queda muy claro
    sera q de casualidad me puedan ayudar
    tengo este problema

    tengo dos tablas en una de ellas nesecito borrar por a clave las 2 comparten la misma clave,
    lo qu tengo que hacer es un trigger q cuando borre de la tabla primaria el trigger busque si esa clave que borre existe en la tabla 2 ese registro
    podrian decirme como q daria mas o menos mi trigger en mysql.

  16. 16
    jesus
    15 de diciembre del 2009 a las 7:49 am

    cree este pero me marca error de sintaxis
    le pregunte e un ing y me digo q tenia que utilizar variables a donde hiba apasar el parametro borrado y despues compararlo en la segunda tabla
    chequenlo y dijanme en que esta mal

    delimiter//
    create trigger borrar
    after delete on animales
    for each row
    begin
    declare unox varchar(25)
    Set unox=animales.cve_animal
    set old.cve_animal=unox
    delete from concursos where concursos.cve_animal=old.cve_animal;
    end
    // delimiter

  17. 17
    Rodrigo Hernandez
    31 de diciembre del 2009 a las 5:05 pm

    Excelente post, muchas gracias
    y ¡¡¡Feliz Año Nuevo!!!

  18. 18
    David
    1 de enero del 2010 a las 4:39 am

    Gracias!!! Feliz año igualmente!!!

  19. 19
    Diego
    20 de enero del 2010 a las 1:41 pm

    una vez que creo el trigger, como lo puedo modificar una vez que abro de nuevo el MySql?
    Gracias