在不调用触发器的情况下在mysql中进行查询(如何禁用触发器)

时间:2022-09-20 13:01:14

I have 2 tables: comments and comments_likes.

我有2个表:评论和评论_likes。


comments

注释

id     
message
likes  

triggers:

触发:

AFTER DELETE

删除后

DELETE FROM comments_likes WHERE comment_id = OLD.id;

comments_likes

comments_likes

id        
comment_id

triggers:

触发:

AFTER INSERT

插入后

UPDATE comments SET likes = likes + 1 WHERE comments.id = NEW.comment_id;

AFTER DELETE

删除后

UPDATE comments SET likes = likes - 1 WHERE comments.id = OLD.comment_id;

AFTER UPDATE

更新后

**omited code, updates comments**

So the question is, can I disable the triggers when activating them from another trigger?

所以问题是,我可以在从另一个触发器激活触发器时禁用触发器吗?

What I want is do something likes this:

我想要的是做这样的事情:

AFTER DELETE

删除后

IF NOT called_from_another_trigger() THEN
    UPDATE comments SET likes = likes - 1 WHERE comments.id = OLD.comment_id;
END IF;

[EDIT]

[编辑]

A non optimized solution would be (very slow query... makes a query for each LIKE register):

一个非优化的解决方案是(非常慢的查询...对每个LIKE寄存器进行查询):

BEGIN
    IF (SELECT id FROM comments WHERE comments.id = OLD.comment_id) THEN
        UPDATE comments SET comments.cache_likes = comments.cache_likes - 1 WHERE comments.id = OLD.comment_id;
    END IF;
END

UPDATE LOW PRIORITY and IGNORE don't works.

UPDATE LOW PRIORITY和IGNORE不起作用。

[EDIT 2]

[编辑2]

I have another idea, is possible to set a global variable in the first trigger and read it from the other trigger?

我有另一个想法,可以在第一个触发器中设置一个全局变量并从另一个触发器读取它吗?

Ex:

例如:

first trigger:

第一次触发:

@disable_triggers = true;
// do the stuff that calls another triggers
@disable_triggers = false;

other trigger:

其他触发器:

if @disable_triggers = false then
    // do the stuff
end if;

3 个解决方案

#1


22  

To disable triggers you can do:

要禁用触发器,您可以:

Trigger 1

触发1

SET @disable_trigger = 1;
// do stuff that calls trigger 2
SET @disable_trigger = NULL;

Trigger 2

触发2

IF @disable_trigger IS NULL THEN
    // do stuff only if called from a query and not from trigger 1
END IF;

#2


1  

Can be a bit ugly, but what i do is rename the table to table2 which the trigger does not attach too, and then, on the end, rename back.

可能有点难看,但我所做的是将表重命名为table2,触发器也没有附加,然后,最后重命名。

#3


0  

No you can't. That's the point of triggers: to be run always.

不,你不能。这就是触发点:永远运行。

Besides, I can't see why you would need that in your case. At worst nothing gets updated - no errors will be raised.

此外,我不明白你为什么需要这种情况。最糟糕的是没有任何更新 - 不会出现任何错误。

You can always add a condition in your trigger, to check if they (or part of their code) should be run (for example if there is a record in relevant table).

您始终可以在触发器中添加条件,以检查是否应运行它们(或其代码的一部分)(例如,如果相关表中有记录)。

#1


22  

To disable triggers you can do:

要禁用触发器,您可以:

Trigger 1

触发1

SET @disable_trigger = 1;
// do stuff that calls trigger 2
SET @disable_trigger = NULL;

Trigger 2

触发2

IF @disable_trigger IS NULL THEN
    // do stuff only if called from a query and not from trigger 1
END IF;

#2


1  

Can be a bit ugly, but what i do is rename the table to table2 which the trigger does not attach too, and then, on the end, rename back.

可能有点难看,但我所做的是将表重命名为table2,触发器也没有附加,然后,最后重命名。

#3


0  

No you can't. That's the point of triggers: to be run always.

不,你不能。这就是触发点:永远运行。

Besides, I can't see why you would need that in your case. At worst nothing gets updated - no errors will be raised.

此外,我不明白你为什么需要这种情况。最糟糕的是没有任何更新 - 不会出现任何错误。

You can always add a condition in your trigger, to check if they (or part of their code) should be run (for example if there is a record in relevant table).

您始终可以在触发器中添加条件,以检查是否应运行它们(或其代码的一部分)(例如,如果相关表中有记录)。