CREATE TRIGGER nombre_disp momento_disp evento_disp ON nombre_tabla FOR
EACH ROW sentencia_disp
nombre_disp: nombre del trigger
momento_disp: before/after
evento_disp: insert/update/delete
(No puede haber dos disparadores en una misma tabla que correspondan al mismo
momento y sentencia)
nombre_tabla
sentencia_disp: Comando a ejecutar
Ejemplo:
CREATE TABLE test1(a1 INT); //tablas que se usan como ejemplo
CREATE TABLE test2(a2 INT); //tablas que se usan como ejemplo
CREATE TRIGGER testref AFTER INSERT ON test1 //Nombre del trigger y tabla
que se afectara
FOR EACH ROW //Las filas que se afectaran después de la ejecución del
trigger
BEGIN
INSERT INTO test2 SET a2 = NEW.a1; //Datos que serán cambiados por los
nuevos datos
END
|//Fin de la declaración del trigger
Notas:
El alias OLD hace referencia a un registro ya existente antes de un update o delete.
El alias NEW hace referencia a un registro nuevo después de un insert o update.
La sentencia CREATE TRIGGER necesita el privilegio SUPER.
Limitaciones (dependiendo de la versión de MySQL):
Un trigger no puede hacer referencia a una tabla por su nombre, excepto a través de
OLD y NEW (sólo aplicable a comandos SELECT)
Un trigger no puede hacer llamadas a stored procedures (no se puede usar la
sentencia CALL)
No pueden utilizarse transacciones en un trigger
Creamos un archivo de texto que le llamaremos [Link] Que
será el cual almacenará nuestro código SQL que de ahora en adelante
pondré en negrita.
- Creamos la base de datos:
DROP DATABASE IF EXISTS MYDB;
CREATE DATABASE MYDB;
USE MYDB;
- Crearemos las tablas de apuntes y saldos del tipo InnoDB, con una clave
primaria para identificar cada registro de la tabla como único.
DROP TABLE IF EXISTS APUNTES;
CREATE TABLE APUNTES (
ASIENTO INT(8) DEFAULT 0,
LINEA SMALLINT(5) DEFAULT 0,
FECHA DATE DEFAULT ‘2006-01-01’,
TEXTO VARCHAR(40) default '',
CUENTA CHAR(10) default '',
DEBE DOUBLE(10,2) DEFAULT 0,
HABER DOUBLE(10,2) DEFAULT 0,
PRIMARY KEY (ASIENTO,LINEA),
KEY K2(CUENTA, FECHA) )
ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
- Creamos la tabla de Saldos, también con una clave primaria única.
DROP TABLE IF EXISTS SALDO;
CREATE TABLE SALDO (
CUENTA CHAR(10) NOT NULL default '',
ANO SMALLINT(4) DEFAULT 0,
MES TINYINT(2) DEFAULT 0,
DEBE DOUBLE(10,2) DEFAULT 0,
HABER DOUBLE(10,2) DEFAULT 0,
PRIMARY KEY (CUENTA,ANO,MES) )
ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
- Vamos a proceder a crear los Triggers, para la tabla de apuntes.
- Primero el trigger de inserción de registros.
Atención a los delimitadores y al punto y coma de final de sentencia.
Remarcar que los saldos se actualizan después de entrar un registro en la
tabla de apuntes (AFTER INSERT) .
Muy interesante es la orden: INSERT INTO ... ON DUPLICATE KEY
UPDATE.
Esta sentencia inserta un registro en la tabla de saldos, y si este existiera,
actualiza solamente las columnas debe y haber. Por eso hemos definido
claves primarias (PRIMARY KEY) en las tablas, requisito indispensable
para que esta sentencia funcione.
DELIMITER //
CREATE TRIGGER APTS_I AFTER INSERT ON APUNTES
FOR EACH ROW
BEGIN
INSERT INTO SALDO SET
[Link]=[Link],
[Link]=YEAR([Link]),
[Link]=MONTH([Link]),
[Link]=[Link],
[Link]=[Link]
ON DUPLICATE KEY UPDATE
[Link]=[Link]+[Link],
[Link]=[Link]+[Link] ;
END;//
DELIMITER ;
- Creamos el trigger de actualización o modificación de asientos:
Es importante resaltar las equivalencias de código:
MySQL FoxPro
[Link] OLDVAL(“DEBE”,”APUNTES”)
E
[Link] CURVAL(“DEBE”,”APUNTES”)
E
DELIMITER //
CREATE TRIGGER APTS_U AFTER UPDATE ON APUNTES
FOR EACH ROW
BEGIN
INSERT INTO SALDO SET
[Link]=[Link],
[Link]=YEAR([Link]),
[Link]=MONTH([Link]),
[Link]=[Link]*(-1),
[Link]=[Link]*(-1)
ON DUPLICATE KEY UPDATE
[Link]=[Link]+([Link]*(-1)),
[Link]=[Link]+([Link]*(-1)) ;
INSERT INTO SALDO SET
[Link]=[Link],
[Link]=YEAR([Link]),
[Link]=MONTH([Link]),
[Link]=[Link],
[Link]=[Link]
ON DUPLICATE KEY UPDATE
[Link]=[Link]+[Link],
[Link]=[Link]+[Link] ;
END;//
DELIMITER ;
- Por último creamos el trigger de eliminación de apuntes
DELIMITER //
CREATE TRIGGER APTS_D AFTER DELETE ON APUNTES
FOR EACH ROW
BEGIN
INSERT INTO SALDO SET
[Link]=[Link],
[Link]=YEAR([Link]),
[Link]=MONTH([Link]),
[Link]=[Link]*(-1),
[Link]=[Link]*(-1)
ON DUPLICATE KEY UPDATE
[Link]=[Link]+([Link]*(-1)),
[Link]=[Link]+([Link]*(-1)) ;
END;//
DELIMITER ;
- Grabamos el archivo [Link]
- Vamos al prompt del MySQL con el usuario root. Para estar seguros de
tener todos los privilegios necesarios, y ejecutamos el código de ejemplo.
- Vamos ahora a crear un archivo de código MySQL que le denominaremos
[Link] y que va ha contener 2 asientos contables.
Correspondientes a una factura y el cobro de la misma al mes siguiente.
Utilizaremos transacciones.
USE MYDB;
SET AUTOCOMMIT=0 ;
START TRANSACTION ;
INSERT INTO APUNTES VALUES (1,1,'2006-02-07','Fra.112 PEPE PALO','4300000001',1160,0);
INSERT INTO APUNTES VALUES (1,2,'2006-02-07','Fra.112 PEPE PALO','4770000001',0,160);
INSERT INTO APUNTES VALUES (1,3,'2006-02-07','Fra.112 PEPE PALO','7000000000',0,1000);
INSERT INTO APUNTES VALUES (2,1,'2006-03-20','Cobro Fra.112 PEPE
PALO','5700000000',1160,0);
INSERT INTO APUNTES VALUES (2,2,'2006-03-20','Cobro Fra.112 PEPE
PALO','4300000001',0,1160);
COMMIT;
Grabamos el archivo [Link] . Vamos al prompt de MySQL y ejecutamos el código.
Ahora hacemos un SELECT de la tabla SALDOS y ...Voilà.