大家好我的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 ;