MySQL在插入后更新相同的表

MySQL在插入后更新相同的表,mysql,triggers,Mysql,Triggers,考虑下表夫妻,其中男性是主键: male female David Maria John Victoria Paul Sara Steve Anna 现在,假设您创建了一个后插入触发器: BEGIN UPDATE `couples` SET `female`='Brenda' WHERE `male`='Peter'; END 起初,您可能认为插入一个新的男性记录Peter会触发自动将女性记录填充为Brenda。然而,情况并非如此: INSERT INTO `

考虑下表
夫妻
,其中
男性
是主键:

male female
David Maria
John Victoria
Paul Sara
Steve Anna
现在,假设您创建了一个后插入触发器:

BEGIN    
    UPDATE `couples` SET `female`='Brenda'
    WHERE `male`='Peter';    
END
起初,您可能认为插入一个新的男性记录
Peter
会触发自动将女性记录填充为
Brenda
。然而,情况并非如此:

INSERT INTO `couples` (`male`) VALUES ('Peter');

MySQL said:    
#1442 - Can't update table 'couples' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.  
根据其他几篇文章,这是为了避免递归循环

问题
每次插入新的男性记录时,都需要填写女性记录。但是,只有在实际创建了新记录时(选择after trigger的原因),才应执行此操作。
在MySQL中有可能做到这一点吗?有解决办法吗?
还是应该在应用程序级别执行此操作

每次插入新的男性记录时,都需要填写女性记录。但是,只有在实际创建了新记录时才应执行此操作(选择after触发器的原因)

仅在创建行时应用更改的要求是不必要的,因为如果行违反约束,则不会创建该行,无论是否修改新行中的值

正如@juergend在上面所评论的,在INSERT触发器之前,使用
中的
SET
语句更改女性列

BEGIN    
    SET NEW.`female` = CASE NEW.`male` WHEN 'Peter' THEN 'Brenda' END;
END
如果插入是主键冲突,则整个插入将被取消,并且您尝试插入的整行将被丢弃,以及插入前触发器中设置的修改值

如果插入不是主键冲突,则该行将成功插入,并且它将包括您在插入前触发器中设置的值

不能更改AFTER触发器中的列值

说:

在BEFORE触发器中,如果您对其具有更新权限,还可以使用SET NEW.col_name=value更改其值。这意味着您可以使用触发器修改要插入新行或用于更新行的值。(这样的SET语句在AFTER触发器中无效,因为行更改已经发生。

(强调矿山)


你似乎专注于避免给
female
列赋值,所以我想这不仅仅是一个简单的'Brenda'赋值。我想您会担心,因为这一定是一个代价高昂的SQL查询

我建议在这种情况下,您需要将其设置为一个快速SQL查询。优化您需要执行的任何查找,以找到“Brenda”的值,这样就不会有太大的开销,然后从触发器前调用它

唯一的另一个选项是保留
女性
列,或者将其设置为某个占位符值。然后,在应用程序确认插入成功后(受影响的行为1),然后发出更新以设置
female
列的值


但你不能在一次触发后就这么做,句号。

只需使用
SET NEW.female='Brenda'
而不使用
update
等等。@juergend MySQL说:#1362-在触发后不允许更新新行将其更改为
之前
@juergend重要的是,只有在实际创建了新记录时才会进行填空过程(选择after trigger的原因)。否则,将不必要地请求多个过程调用。我想您不会得到after trigger和before trigger之间的区别。只有在创建记录时才会调用这两个过程。假设我使用诸如
SELECT SLEEP(30)之类的after trigger执行
插入成对(男性)值('David')
.MySQL将等待30秒,然后继续执行以下消息:
#1062-对键“PRIMARY”重复输入“David”
。但是,这不是我希望它的行为方式……现在,执行相同的
插入夫妇(男性)值('David')
,但使用后触发器,例如
选择睡眠(30)
.MySQL将返回重复条目冲突的相同消息,但不会等待30秒。因此,没有运行after触发器。这是我希望它的行为方式(但是,我需要更新行值,而不是睡眠)。好吧,你不能在触发器中这样做。对不起,MySQL就是这样工作的。我不知道还有什么可以告诉你的。是否可以在before触发器中设置一个条件,说明以下内容:如果没有具有此类男性值的记录,则更新女性对应项,否则什么也不做???你可以从表中选择,但这会创建竞争条件,因为某些其他会话可能同时插入到表中。