MySQL触发器问题

时间:2016-01-20 21:17:51

标签: mysql triggers

大家好我的MySQL触发器有一些问题,我需要我的触发器告诉我,如果成分在光标中,ingredientesMenu也在ingredientesPaciente光标中。 在了解患者是否可以根据他可以吃的成分吃菜单的成分时。 问题是,对于你输入的任何菜单,触发器告诉我含有患者不能吃的成分。

P.D。:Srry因为英语不好。

drop trigger comidaAdecuada;

DELIMITER //

CREATE TRIGGER comidaAdecuada
BEFORE INSERT ON PACIENTE_COME
FOR EACH ROW
BEGIN

    DECLARE menuIngrediente INT;
    DECLARE aux INT;
    DECLARE cantidadI INT;
    DECLARE sVariable INT;

    DECLARE ingredientesMenu CURSOR FOR
        SELECT id_ingrediente
        FROM COMIDA_INGREDIENTE NATURAL JOIN MENU_COMIDA
        WHERE id_menu = NEW.id_menu;

    DECLARE cantidadIngredientes CURSOR FOR 
        SELECT cantidad
        FROM INGREDIENTE NATURAL JOIN COMIDA_INGREDIENTE NATURAL JOIN MENU_COMIDA
        WHERE id_menu = NEW.id_menu;

    DECLARE ingredientesPaciente CURSOR FOR 
        SELECT id_ingrediente
        FROM INGREDIENTE_ENFERMEDAD NATURAL JOIN PACIENTE_ENFERMEDAD
        WHERE dni_paciente = NEW.dni_paciente;

    OPEN ingredientesMenu;
    OPEN ingredientesPaciente;
    OPEN cantidadIngredientes;

    FETCH NEXT FROM ingredientesMenu INTO menuIngrediente;
    FETCH NEXT FROM cantidadIngredientes INTO cantidadI;

    read_loop: WHILE (FETCH_STATUS = 0) DO

        IF(cantidadI = 0) THEN
            SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'No quedan ingredientes para el menú proporcionado';
            LEAVE read_loop;
        END IF;

        SET aux = (SELECT id_ingrediente FROM ingredientesPaciente WHERE id_ingrediente = menuIngrediente);

        IF(aux = menuIngrediente) THEN
            SET sVariable = 0;
        ELSE
            SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Se ha detectado un ingrediente no adecuado para el paciente en el menú propuesto.';
            LEAVE read_loop;
        END IF;

        FETCH NEXT FROM ingredientesMenu INTO menuIngrediente;
        FETCH NEXT FROM cantidadIngredientes INTO cantidadI;

    END WHILE;

    CLOSE ingredientesMenu;
    CLOSE ingredientesPaciente;
    CLOSE cantidadIngredientes;

END;

//

DELIMITER ;

好的,我改变了代码和语法不再有问题,但仍然没有做我喜欢的事。

现在总是插入,即使成分对患者不利。

新守则:

drop trigger comidaAdecuada;

DELIMITER //

CREATE TRIGGER comidaAdecuada
BEFORE INSERT ON PACIENTE_COME
FOR EACH ROW
BEGIN

    DECLARE menuIngrediente INT;
    DECLARE aux INT;
    DECLARE cantidadI INT;
    DECLARE done INT DEFAULT FALSE;

    DECLARE ingredientesMenu CURSOR FOR
        SELECT id_ingrediente
        FROM COMIDA_INGREDIENTE NATURAL JOIN MENU_COMIDA
        WHERE id_menu = NEW.id_menu;

    DECLARE cantidadIngredientes CURSOR FOR 
        SELECT cantidad
        FROM INGREDIENTE NATURAL JOIN COMIDA_INGREDIENTE NATURAL JOIN MENU_COMIDA
        WHERE id_menu = NEW.id_menu;

    DECLARE ingredientesPaciente CURSOR FOR 
        SELECT id_ingrediente
        FROM INGREDIENTE_ENFERMEDAD NATURAL JOIN PACIENTE_ENFERMEDAD
        WHERE dni_paciente = NEW.dni_paciente;


    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    OPEN ingredientesMenu;
    OPEN ingredientesPaciente;
    OPEN cantidadIngredientes;

    FETCH NEXT FROM ingredientesMenu INTO menuIngrediente;
    FETCH NEXT FROM cantidadIngredientes INTO cantidadI;

    read_loop: LOOP

        IF done THEN
            LEAVE read_loop;
        END IF;

        IF(cantidadI = 0) THEN
            SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'No quedan ingredientes para el menú proporcionado';
            LEAVE read_loop;
        END IF;

        SET aux = (SELECT id_ingrediente FROM ingredientesPaciente WHERE id_ingrediente = menuIngrediente);

        IF(aux <> menuIngrediente) THEN
            SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Se ha detectado un ingrediente no adecuado para el paciente en el menú propuesto.';
            LEAVE read_loop;
        END IF;

        FETCH NEXT FROM ingredientesMenu INTO menuIngrediente;
        FETCH NEXT FROM cantidadIngredientes INTO cantidadI;

    END LOOP;

    CLOSE ingredientesMenu;
    CLOSE ingredientesPaciente;
    CLOSE cantidadIngredientes;

END;

//

DELIMITER ;

特别感谢Uueerdo的帮助。

我解决了我的问题,我在使用CURSOR时遇到了一些问题,但现在代码还可以。

drop trigger comidaAdecuada;

DELIMITER //

CREATE TRIGGER comidaAdecuada
BEFORE INSERT ON PACIENTE_COME
FOR EACH ROW
trigger_label: BEGIN

    DECLARE menuIngrediente INT;
    DECLARE aux INT;
    DECLARE cantidadI INT;
    DECLARE done INT DEFAULT FALSE;
    DECLARE numeroIngredientes INT;
    DECLARE cantidadIngredientes INT;

    DECLARE ingredientesMenu CURSOR FOR
        SELECT DISTINCT id_ingrediente
        FROM COMIDA_INGREDIENTE NATURAL JOIN MENU_COMIDA
        WHERE id_menu = NEW.id_menu;

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    SET numeroIngredientes = (SELECT COUNT(*)
                            FROM INGREDIENTE
                            WHERE id_ingrediente IN (
                                SELECT DISTINCT id_ingrediente
                                FROM INGREDIENTE NATURAL JOIN COMIDA_INGREDIENTE
                                WHERE id_comida IN (
                                    SELECT id_comida
                                    FROM COMIDA_INGREDIENTE NATURAL JOIN MENU_COMIDA
                                    WHERE id_menu = NEW.id_menu
                                    )));

    SET cantidadIngredientes = (SELECT COUNT(*)
                            FROM INGREDIENTE
                            WHERE id_ingrediente IN (
                                SELECT DISTINCT id_ingrediente
                                FROM INGREDIENTE NATURAL JOIN COMIDA_INGREDIENTE
                                WHERE INGREDIENTE.cantidad > 0 AND id_comida IN (
                                    SELECT id_comida
                                    FROM COMIDA_INGREDIENTE NATURAL JOIN MENU_COMIDA
                                    WHERE id_menu = NEW.id_menu
                                    )));

    IF(cantidadIngredientes <> numeroIngredientes) THEN
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'No quedan ingredientes para el menú proporcionado';
        LEAVE trigger_label;
    END IF;

    OPEN ingredientesMenu;

    read_loop: LOOP

        FETCH NEXT FROM ingredientesMenu INTO menuIngrediente;

        IF done THEN
            LEAVE read_loop;
        END IF;

        SET aux = (SELECT DISTINCT COUNT(*) FROM
                        (SELECT DISTINCT id_ingrediente
                        FROM INGREDIENTE_ENFERMEDAD NATURAL JOIN PACIENTE_ENFERMEDAD
                        WHERE dni_paciente = NEW.dni_paciente) INGREDIENTES_PACIENTE
                    WHERE INGREDIENTES_PACIENTE.id_ingrediente = menuIngrediente);

        IF(aux < 1) THEN
            SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Se ha detectado un ingrediente no adecuado para el paciente en el menú propuesto.';
            LEAVE trigger_label;
        END IF;

        SET aux = 0;

    END LOOP;

    CLOSE ingredientesMenu;
END;

//

DELIMITER ;

0 个答案:

没有答案