MySQL INSERT INTO inside UPDATE 并将新主键设置为外键

Posted

技术标签:

【中文标题】MySQL INSERT INTO inside UPDATE 并将新主键设置为外键【英文标题】:MySQL INSERT INTO inside UPDATE and SET new primary key as foreign key 【发布时间】:2021-03-18 19:28:03 【问题描述】:

我有一个表,其中一些引用的datastores 已被删除,并且它们的外键引用为空。我需要插入一个新的datastore 并在引用表中设置外键。

所有的 ID 都是 UUIDs,我的伪查询看起来像这样但不起作用:

UPDATE `rcachievements_player_achievements`
SET data_id = (INSERT INTO `rcachievements_datastore` (data) VALUES ('"count":0'))
WHERE data_id is null

有没有办法插入datastore,然后在data_id 字段中为缺少数据存储的每一行设置id

【问题讨论】:

你在哪里设置你要插入的行的id 非常奇怪的算法...如果存在data_id is null 的行,那么必须更新所有行吗?如果没有这样的行,那么就不需要相应地更新任何行? 是的,每行缺少数据存储都必须获得自己的新存储。 【参考方案1】:

您必须将其作为多个查询进行。首先将新行插入rcachievements_datastore,然后更新所有引用行。

SET @id = UUID();
INSERT INTO `rcachievements_datastore` (id, data) VALUES (@id, '"count":0');

UPDATE `rcachievements_player_achievements`
SET data_id = @id
WHERE data_id is null;

【讨论】:

这不起作用,因为它只会生成一个商店。但我需要每个丢失的 data_id 一个商店(超过 3000 个) 在这种情况下,您需要使用带循环的语言,而不是 SQL。 你可以在 mysql 中使用存储过程来完成。【参考方案2】:

我最终使用了FOR LOOP,如下所示:

DELIMITER //

FOR i IN (SELECT id FROM `rcachievements_player_achievements` WHERE data_id is NULL)
DO
        SET @id = UUID();
        INSERT INTO `rcachievements_datastore` (id, data, version, when_created, when_modified) VALUES (@id, '"count":0', 1, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP());
        UPDATE `rcachievements_player_achievements` SET data_id = @id WHERE id = i.id;
END FOR;
//

DELIMITER ;

SELECT id FROM `rcachievements_player_achievements` WHERE data_id is NULL;

【讨论】:

以上是关于MySQL INSERT INTO inside UPDATE 并将新主键设置为外键的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 关于表复制 insert into 语法的详细介绍

MYSQL insert into select 锁表问题

MySQL中的insert into 与replace into用法和区别

insert NULL into mysql

mysql insert into 多条数据

MySQL中的insert ignore into, replace into等的一些用法小结(转)