我正在构建一个触发器
CREATE TRIGGER `address_control_update` BEFORE UPDATE ON `orders_shipping`
FOR EACH ROW
BEGIN
SET @error_msg_id := (SELECT `error_msg_id` FROM `orders_err` WHERE orderID = OLD.orderID);
IF(LENGTH(NEW.ShippingName) = 0 OR NEW.ShippingName IS NULL) THEN
INSERT INTO `orders_err` (orderID,error_msg_id) VALUES(NEW.orderID,100) ON DUPLICATE KEY UPDATE complete=false;
ELSEIF (100 IN (SELECT @error_msg_id)) THEN
UPDATE `orders_err` SET complete = true WHERE orderID = OLD.orderID AND error_msg_id = 100;
END IF;
END;//
我想首先查看 orderID 上是否有任何 error_msg_id,然后在 elseif 语句中使用它来查看可能的错误是否已完成。 如果我这样做就可以了
IF(LENGTH(NEW.ShippingName) = 0 OR NEW.ShippingName IS NULL) THEN
INSERT INTO `orders_err` (orderID,error_msg_id) VALUES(NEW.orderID,100) ON DUPLICATE KEY UPDATE complete=false;
ELSEIF EXISTS(SELECT * FROM orders_err WHERE orderID = OLD.orderID AND error_msg_id = 100) THEN
UPDATE `orders_err` SET complete = true WHERE orderID = OLD.orderID AND error_msg_id = 100;
END IF;
但如果可能的话,我只想调用一次 select,因为我在 orders_shipping
表中的其他列上有 12 个类似的 if 语句。
更新时出现错误:错误 1242: 1242: 子查询返回超过 1 行
提前致谢
最佳答案
一种可能的解决方案是使用 GROUP_CONCAT(..) function 将 id 连接到一个以逗号分隔的字符串。 - 那么第一个 SELECT 语句将返回一行。要测试 id 是否在字符串中,请使用 FIND_IN_SET(..) function :
CREATE TRIGGER `address_control_update` BEFORE UPDATE ON `orders_shipping`
FOR EACH ROW
BEGIN
SET @error_msg_ids = (
SELECT GROUP_CONCAT(DISTINCT `error_msg_id`)
FROM `orders_err`
WHERE orderID = OLD.orderID
GROUP BY orderID);
IF(LENGTH(NEW.ShippingName) = 0 OR NEW.ShippingName IS NULL) THEN
INSERT INTO `orders_err` (orderID,error_msg_id) VALUES(NEW.orderID,100) ON DUPLICATE KEY UPDATE complete=false;
ELSEIF (FIND_IN_SET(100, @error_msg_ids)) THEN
UPDATE `orders_err` SET complete = true WHERE orderID = OLD.orderID AND error_msg_id = 100;
END IF;
END;//
而且我认为还存在其他可能性。例如,您可以编写没有 SELECT 语句的代码:
IF(LENGTH(NEW.ShippingName) = 0 OR NEW.ShippingName IS NULL) THEN
INSERT INTO `orders_err` (orderID,error_msg_id) VALUES(NEW.orderID,100) ON DUPLICATE KEY UPDATE complete=false;
ELSE
UPDATE `orders_err` SET complete = true WHERE orderID = OLD.orderID AND error_msg_id = 100;
END IF;
为什么 - 因为您在 SELECT 和 UPDATE 中使用相同的过滤条件 - 因此无需在更新之前测试相同的条件。
关于MySQL TRIGGER 带有由 IN 确定的 IF 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26163930/