lunes, 4 de noviembre de 2013

Select adentro de un trigger en MySql

A la hora de hacer un trigger en ocaciones nos es necesario obtener información de otras tablas ademas de la que está siendo tratada por el trigger, en la mayoría de los manuales que encontré hablan solamente de un registro, en este caso trataremos para más de un registro.

En nuestro caso hipotético crearemos 3 tablas, una donde estarán los vehículos, una donde tendremos los tipos de mantenimiento que se puedan dar y otra donde estarán el listado de los vehículos con los mantenimientos, es decir, será una tabla transaccional donde relacionaremos cada vehículo con cada mantenimiento.

El trigger insertará registros por cada vehículo ingresado en la primer tabla mencionada, obteniendo los id de cada tipo de mantenimiento en la segunda tabla y almacenando un registro por cada tipo de mantenimiento para el vehículo recién ingresado.

Primero crearemos la base de datos:

CREATE DATABASE `vehiculos_manttos`;



Tendremos 3 tablas, una llamada vehiculos con un id y un nombre, para simplificar las cosas:

CREATE TABLE `vehiculos` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nombre` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ;

La segunda tabla la llamaremos mantenimientos_tipo con un id y un nombre:

CREATE TABLE `mantenimientos_tipo` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `mantenimiento_tipocol` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`id`)
);

La tercera tabla será la transaccional, donde almacenaremos los mantenimientos, se llamará mantenimientos y tendrá un id (Para identificar cada registro), un id_vehiculo (Relacionada con la tabla vehiculos), y un id_tipo (Que estará relacionada con la tabla mantenimientos_tipo).

CREATE TABLE `mantenimientos` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `id_vehiculo` int(11) DEFAULT NULL,
  `id_tipo` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_mantenimientos_1_idx` (`id_vehiculo`),
  KEY `fk_mantenimientos_2_idx` (`id_tipo`),
  CONSTRAINT `fk_mantenimientos_1` FOREIGN KEY (`id_vehiculo`) REFERENCES `vehiculos` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `fk_mantenimientos_2` FOREIGN KEY (`id_tipo`) REFERENCES `mantenimientos_tipo` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
);

Ingresemos un par de datos de prueba para tipo de mantenimientos:

INSERT INTO `mantenimientos_tipo` (`id`, `mantenimiento_tipocol`) VALUES (null, 'Cambio de aceite');

INSERT INTO `mantenimientos_tipo` (`id`, `mantenimiento_tipocol`) VALUES (null, 'Recarga de aire');

Ok, las tablas para nuestro ejemplo están creadas y tenemos un par de datos de prueba, ahora crearemos el trigger:

delimiter $$

CREATE TRIGGER `vehiculos_manttos`.`futures_manttos` --Nombre del trigger
AFTER INSERT ON `vehiculos_manttos`.`vehiculos` --Despues que inserte en la tabla vehiculos
FOR EACH ROW --Por cada registro insertado que haga...
BEGIN
    --Declare variables necesarias
    DECLARE done INT DEFAULT FALSE; --Esta variable controlará el flujo del select, para saber si ya se llegó al último registro
    DECLARE c1 INT;
    DECLARE cur CURSOR FOR SELECT id FROM mantenimientos_tipo; --Se crea un cursos para los registros que devolverá la query 'select id from mantenimientos_tipo;'
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; --Se prepara la bandera como cierta
    OPEN cur; --Entramos en el cursor que tiene los registros
        ins_loop: LOOP
            FETCH cur INTO c1; --Guardamos el registro del id devuelto en c1
            IF done THEN
                LEAVE ins_loop; --Si ya no hay registro entonces que salga del loop
            END IF;
            INSERT INTO mantenimientos VALUES (null,NEW.id,c1); --Insertamos un registro por cada registro de mantenimientos_tipo en mantenimientos con el nuevo id que se creó en el insert que dispara el trigger
        END LOOP;
    CLOSE cur;
END
$$


Despues de unas pruebas te darás cuenta que es menos complicado de lo que parece, haz una prueba insertando un registro en behiculos y verás que se crearán 2 registro en mantenimientos, uno por cada registro de mantenimientos_tipo.

Suerte!

No hay comentarios :

Publicar un comentario