MySQL:事务提交后调用触发器

发布于 2024-10-17 04:15:49 字数 1616 浏览 2 评论 0原文

我有一个非常简单的数据库,具有以下架构:

video (id, title, description)
category (id, name)
tag (id, name)

video_category_reference (video_id, category_id)
video_tag_reference(video_id, tag_id)

abc_table (video_id, description, categories)

前五个表使用 InnoDB 引擎。

最后一个表 - abc_table 使用 MyISAM 引擎,它包含某种“缓存”。 description 列存储 CONCAT(video.title, video.description, GROUP_CONCAT(tag.name)) 的结果,categories 列存储结果GROUP_CONCAT(category.id)

我需要的是一个触发器,它将在创建新视频后填充 abc_table 。新视频将始终以相同的方式创建:

START TRANSACTION;

INSERT INTO video VALUES(NULL, "My video", "description");

SET @vid = (SELECT LAST_INSERT_ID());

INSERT INTO video_category_reference VALUES (@vid, 1), (@vid, 2), (@vid, 3), (@vid, 4);
INSERT INTO video_tag_reference VALUES (@vid, 5), (@vid, 6), (@vid, 7), (@vid, 8);

COMMIT;

不幸的是,我无法使用此触发器:

CREATE TRIGGER after_insert_on_video AFTER INSERT ON video FOR EACH ROW BEGIN
    SET @categories = (SELECT GROUP_CONCAT(category_id) FROM video_category_reference WHERE video_id = NEW.id GROUP BY video_id);
    SET @tags = (SELECT GROUP_CONCAT(t.name) FROM video_tag_reference vtr JOIN tag t ON vtr.tag_id = t.id WHERE video_id = NEW.id GROUP BY video_id);

    INSERT INTO video_search_table VALUES (NEW.id, CONCAT(NEW.title, NEW.raw_description, @tags), @categories);
END$$

...因为它将在 *_reference 表上的插入完成之前执行。


有什么方法可以强制 MySQL 在事务提交后执行触发器吗?或者我是否必须为 *_referemce 表创建将修改 abc_table 中的值的触发器?

I've a very simple database with following schema:

video (id, title, description)
category (id, name)
tag (id, name)

video_category_reference (video_id, category_id)
video_tag_reference(video_id, tag_id)

abc_table (video_id, description, categories)

The first five tables use InnoDB engine.

The last table - abc_table uses MyISAM engine and it contains some kind of "cache". description column stores the result of CONCAT(video.title, video.description, GROUP_CONCAT(tag.name)) and categories column stores the result of GROUP_CONCAT(category.id).

What I need is a trigger that will populate abc_table after a new video is created. A new video will be created always the same way:

START TRANSACTION;

INSERT INTO video VALUES(NULL, "My video", "description");

SET @vid = (SELECT LAST_INSERT_ID());

INSERT INTO video_category_reference VALUES (@vid, 1), (@vid, 2), (@vid, 3), (@vid, 4);
INSERT INTO video_tag_reference VALUES (@vid, 5), (@vid, 6), (@vid, 7), (@vid, 8);

COMMIT;

Unfortunately I can't use this trigger:

CREATE TRIGGER after_insert_on_video AFTER INSERT ON video FOR EACH ROW BEGIN
    SET @categories = (SELECT GROUP_CONCAT(category_id) FROM video_category_reference WHERE video_id = NEW.id GROUP BY video_id);
    SET @tags = (SELECT GROUP_CONCAT(t.name) FROM video_tag_reference vtr JOIN tag t ON vtr.tag_id = t.id WHERE video_id = NEW.id GROUP BY video_id);

    INSERT INTO video_search_table VALUES (NEW.id, CONCAT(NEW.title, NEW.raw_description, @tags), @categories);
END$

...as it will be executed before inserts on *_reference tables will be done.


Is there any way I could force MySQL to execute a trigger after the transaction is commited? Or do I have to create triggers for *_referemce tables that will modify values in abc_table?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

爱的十字路口 2024-10-24 04:15:49

您可以将触发器更改为“更新后”,并快速:

UPDATE video SET id=@vid WHERE id=@vid;

在事务结束之前触发触发器。奖励:如果您的视频信息更新,触发器将再次运行=D。

You could change your trigger to AFTER UPDATE and have a quick:

UPDATE video SET id=@vid WHERE id=@vid;

to trigger the trigger before the transaction ends. Bonus: if your video information is updated, the trigger runs again =D.

岁吢 2024-10-24 04:15:49

使用触发器正是因为它们发生在事务内:如果触发器中发生错误,则整个事务回滚,不会出现混乱的孤儿或部分数据。

因此,最好的办法是重新设计表,以便(希望)一个表上的单个触发器能够解决问题。

Triggers are used precisely because they occur within the transaction: if an error occurs in a trigger, the entire transaction rolls back, no messy orphans or partial data.

So the best thing is to rework the tables so that (hopefully) a single trigger on one table will do the trick.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文