如何创建 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 件事必须是完成
- 如果销售付款方式不是 CREDIT,您可以有一种或多种付款方式但没有 CREDIT
- 我们不得将相同的付款方式多次关联到同一销售 ID
- 第 3 个有点多余,但如果一种销售付款方式是 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 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
你好,我正在尝试为 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 件事必须是完成
- 如果销售付款方式不是 CREDIT,您可以有一种或多种付款方式但没有 CREDIT
- 我们不得将相同的付款方式多次关联到同一销售 ID
- 第 3 个有点多余,但如果一种销售付款方式是 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 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