【问题标题】:How to creatae MySQL trigger如何创建 MySQL 触发器
【发布时间】:2021-12-16 23:43:39
【问题描述】:

您好,我正在尝试为类似这样的表编写触发器:

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 并且可以在不付款的情况下拿走产品,这些验证在其他地方进行,但在此表中必须完成这 3 件事

  • 如果销售付款方式不是 CREDIT,您可以有一种或多种付款方式但没有 CREDIT
  • 我们不能多次将相同的付款方式关联到同一个销售 ID
  • 第三个有点多余,但如果一种销售付款方式是 CREDIT,我们不能允许另一种付款方式

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

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 collat​​ion' 我认为那是因为 paymentMethod 是 VARCHAR 并且 payment 是一个枚举,但我不知道怎么解决。

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

谢谢!

【问题讨论】:

    标签: mysql triggers


    【解决方案1】:

    如果默认字符集与您在 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)
    
    此付款方式已与此 ID 关联

    db小提琴here

    【讨论】:

    • 哦,我的天哪,我从来没有想过这个角色集有事可做。很明显这就是为什么它说非法整理,谢谢你指出我,谢谢!
    猜你喜欢
    • 2011-02-03
    • 2016-09-19
    • 2016-10-20
    • 1970-01-01
    • 1970-01-01
    • 2015-02-23
    • 2013-07-26
    • 2015-03-01
    • 2013-07-16
    相关资源
    最近更新 更多