我有一个名为pledgeRating
的表,用于存储用户评分。在每个插入中,我运行以下触发器来更新ratingsCount
表中的rating
和pledgeTemplate
列:
CREATE DEFINER=`trigger`@`%` TRIGGER `project87`.`pledgeRating_AFTER_INSERT` AFTER INSERT ON `pledgeRating` FOR EACH ROW
BEGIN
UPDATE `pledgeTemplate`
SET `rating` = ((`rating` * `ratingsCount`) + NEW.rating) / (`ratingsCount` + 1),
`ratingsCount` = `ratingsCount` + 1
WHERE `id` = NEW.pledgeTemplateID;
END
为了完整起见,我想阻止所有mysql用户直接更新ratingsCount
表中的rating
和pledgeTemplate
列。我希望仅从触发器更新这两列。
为了实现这一点,我在pledgeTemplate
表中创建了一个新的触发器来验证运行更新查询的用户,但我找不到一种方法来检测该更新是否来自触发器:
CREATE DEFINER=`trigger`@`%` TRIGGER `project87`.`pledgeTemplate_BEFORE_UPDATE` BEFORE UPDATE ON `pledgeTemplate` FOR EACH ROW
BEGIN
IF (OLD.ratingsCount != NEW.ratingsCount OR OLD.rating != NEW.rating) AND {{Update query is not from the trigger}} THEN
SIGNAL sqlstate '45000' SET message_text = 'Error: Only trigger can modify ratingsCount or rating columns';
END IF;
END
是否可以从第一个触发器传递一个标志,以便我可以在第二个触发器中检测到查询是否来自触发器?我查看了CURRENT_USER
对象和USER()
函数,因为我认为这些可能会有所帮助。但是CURRENT_USER
总是设置为DEFINER
,USER()
始终返回运行初始查询的用户。
那么,有没有办法检测pledgeTemplate
表上的更新查询是否从触发器或“直接”更新中运行?
答案 0 :(得分:0)
您好_
首先我开始在评论中解释我的想法,但似乎它变得太长而且格式不正确。所以这只是一个想法,我不知道你是否对它好,但我会分享它:
ALTER TABLE pledgeTemplate ADD COLUMN isTriggerUpdate BIT NULL DEFAULT 0;
- 所以我们在表格中添加一个列,我们可以将其用作标志来确定更新是来自触发器还是来自用户2
CREATE DEFINER=`trigger`@`%` TRIGGER `project87`.`pledgeRating_AFTER_INSERT`
AFTER INSERT ON `pledgeRating` FOR EACH ROW
BEGIN
UPDATE `pledgeTemplate`
SET `rating` = ((`rating` * `ratingsCount`) + NEW.rating) / (`ratingsCount` + 1),
`ratingsCount` = `ratingsCount` + 1,
`isTriggerUpdate ` = 1
WHERE `id` = NEW.pledgeTemplateID;
END
更改触发器的代码 pledgeRating_AFTER_INSERT ,将标志列设置为true
3
CREATE DEFINER=`trigger`@`%` TRIGGER `project87`.`pledgeTemplate_BEFORE_UPDATE`
BEFORE UPDATE ON `pledgeTemplate` FOR EACH ROW
BEGIN
IF (OLD.ratingsCount != NEW.ratingsCount OR OLD.rating != NEW.rating)
AND NEW.isTriggerUpdate != 1 THEN
SIGNAL sqlstate '45000' SET message_text = 'Error: Only trigger can modify ratingsCount or rating columns';
END IF;
END
现在你可以像这样在 pledgeTemplate_BEFORE_UPDATE 中找到缺失的条件。
我认为这将作为逻辑工作,但问题是,这是实现这一目标的最有效逻辑。在此逻辑中,您无需在任何情况下将 isTriggerUpdate 列公开到前端,因为只需将其设置为true即可绕过此逻辑......
祝你好运!