如何创建 MySQL 触发器

How to creatae MySQL trigger

你好,我正在尝试为 table table 写一个触发器,就像这样:

CREATE TABLE `sales_payment_method` (
  `id` int(11) NOT NULL,
  `payment` enum('CASH','CARD','CHECK','TRANSFERENCE','CREDIT') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  `amount` decimal(10,2) NOT NULL,
  KEY `id` (`id`),
  CONSTRAINT `sales_payment_method_ibfk_1` FOREIGN KEY (`id`) REFERENCES `sales_info` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

您可以采用不同的付款方式组合,例如,如果您必须支付 100 美元才能进行销售id=15,假设您没有足够的现金,那么您可以使用信用卡和你的现金支付。 这样在 sales_payment_method 中我们可以添加以下两个新行:

INSERT INTO sales_payment_method VALUES (15, 'CASH', 70.00)INSERT INTO sales_payment_method VALUES (15, 'CARD', 30.00)

好吧,虽然我在 PHP 中做了一些验证,但我想使用触发器,这样我可以防止感觉更安全。

除了 CREDIT 之外,所有支付方式在这些标签中的处理方式都类似,这意味着客户拥有 CREDIT 并且可以在不付款的情况下使用产品,这些验证是在其他地方进行的,但是在这个 table 中,这 3 件事必须是完成

我试图通过创建以下触发器来完成前面的几点,但出现了错误

BEGIN
    DECLARE i INT;
    DECLARE paymentMethod VARCHAR(15);
    SELECT COUNT(*)
    INTO i
    FROM sales_payment_method
    WHERE id=NEW.id;
    
    SET paymentMethod = (SELECT payment
    FROM sales_payment_method WHERE 
    id=NEW.id);
    
    IF i= 1 AND NEW.payment = "CREDIT" THEN
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = "You can not use CREDIT when there's already a different payment method";
    END IF;
    IF i= 1 AND paymentMethod LIKE NEW.payment THEN
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = "This payment method is already associated to this ID";
    END IF;
    IF i= 1 AND paymentMethod LIKE "CREDIT" THEN
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = "This sale payment method is CREDIT, you can not use a different payment method";
    END IF;
END

当我尝试插入一些东西来测试触发器时,第一个 IF 似乎工作正常,但我收到 MySQL 1267 错误,'Illegal mix of collations' 我认为那是因为 paymentMethod 是 VARCHAR,而 payment 是一个枚举,但我不知道如何解决它。

希望你能指导我正确的方向。

谢谢!

如果默认字符集与您在 tabem 中使用的字符集不同,您必须定义所有变量,然后使用您使用的字符集和排序规则或至少一个与此类似的字符集和排序规则

CREATE TABLE `sales_payment_method` (
  `id` int(11) NOT NULL,
  `payment` enum('CASH','CARD','CHECK','TRANSFERENCE','CREDIT') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL,
  `amount` decimal(10,2) NOT NULL,
  KEY `id` (`id`)
  #,
  #CONSTRAINT `sales_payment_method_ibfk_1` FOREIGN KEY (`id`) REFERENCES `sales_info` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
CREATE TRIGGER ins_check BEFORE INSERT ON sales_payment_method
       FOR EACH ROW 
BEGIN
    DECLARE i INT;
    DECLARE paymentMethod VARCHAR(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
    SELECT COUNT(*)
    INTO i
    FROM sales_payment_method
    WHERE id=NEW.id;
    
    SET paymentMethod = (SELECT payment
    FROM sales_payment_method WHERE 
    id=NEW.id);
    
    IF i= 1 AND NEW.payment = "CREDIT" THEN
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = "You can not use CREDIT when there's already a different payment method";
    END IF;
    IF i= 1 AND paymentMethod <> NEW.payment THEN
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = "This payment method is already associated to this ID";
    END IF;
    IF i= 1 AND paymentMethod LIKE "CREDIT" THEN
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = "This sale payment method is CREDIT, you can not use a different payment method";
    END IF;
END
INSERT INTO sales_payment_method VALUES (15, 'CASH', 70.00) 
INSERT INTO sales_payment_method VALUES (15, 'CARD', 30.00)
This payment method is already associated to this ID

db<>fiddle here