【发布时间】:2013-06-02 08:23:33
【问题描述】:
我建议使用触发器来检查回答this question 的交叉表完整性约束。在 cmets 中已经提示它可能会导致问题:
执行跨行检查的触发器很少在大多数数据库上工作......因为它们无法从其他事务中读取未提交的行
不过,我还没有找到任何支持该声明的来源。 Official documentation 没有提及任何内容。我发现的其他问题已涵盖here on SO - 它主要批评潜在的隐藏复杂性,因为第一眼看不到触发器。但即使是highest rated answer 也承认它们用于完整性问题。
所以我的问题是:数据库触发器对于跨表完整性约束是否安全?具体来说,下面的解决方案是否可行?
总结原始问题。我们有桌子
- 玩家 - 玩家 ID、玩家名称
- 投注 - BetID、BetName
- plays_in - BetID、PlayerID
约束是 BetName 和 PlayerID 的组合应该是唯一的。建议触发器的定义:
CREATE TRIGGER check_bet_name BEFORE INSERT ON plays_in
FOR EACH ROW BEGIN
DECLARE bet_exists INT DEFAULT 0;
DECLARE msg VARCHAR(255);
SELECT 1 INTO bet_exists
FROM Bet AS b1
WHERE b1.BetID = NEW.BetID
AND EXISTS (SELECT *
FROM plays_in AS p JOIN Bet AS b2 USING (BetID)
WHERE p.PlayerID = NEW.PlayerID AND b2.BetName = b1.BetName
)
LIMIT 1;
IF bet_exists THEN
SET msg = "Bet name already exists...";
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = msg;
END IF;
END//
【问题讨论】:
-
你能否运行一个简单的测试来检查关于无法看到未提交更改的声明(听起来应该是真的)?
-
@Thilo 哦,天哪,你说得对,它真的失败了
标签: mysql sql triggers transactions