admin

带有last_insert_id()的MySQL多行插入选择语句

sql

好的。简而言之,我正在尝试执行INSERT SELECT,例如:

START TRANSACTION;  
INSERT INTO dbNEW.entity (commonName, surname)  
SELECT namefirst, namelast  
FROM dbOLD.user;  
SET @key = LAST_INSERT_ID();  
INSERT INTO dbNEW.user (userID, entityID, other)  
SELECT user_id, @key, other  
FROM dbOLD.user;  
COMMIT;

当然,@key不会从每个插入中返回每个后续的LAST_INSERT_ID(),而是仅从最后一个插入返回ID。

基本上,我将旧的USER表拆分为ENTITY和USER,例如:

 dbOLD.user
 +-------------+---------------------+------+-----+------------+----------------+
 | Field       | Type                | Null | Key | Default    | Extra          |
 +-------------+---------------------+------+-----+------------+----------------+
 | user_id     | int(10) unsigned    | NO   | PRI | NULL       | auto_increment |
 | namefirst   | varchar(20)         | NO   |     |            |                |
 | namelast    | varchar(20)         | NO   |     |            |                |
 | other       | varchar(10)         | NO   |     |            |                |
 +-------------+---------------------+------+-----+------------+----------------+


 dbNEW.user
 +-------------+---------------------+------+-----+------------+----------------+
 | Field       | Type                | Null | Key | Default    | Extra          |
 +-------------+---------------------+------+-----+------------+----------------+
 | userID      | int(10) unsigned    | NO   | PRI | NULL       | auto_increment |
 | entityID    | int(10) unsigned    | NO   | MUL | 0          |                |
 | other       | varchar(10)         | NO   |     |            |                |
 +-------------+---------------------+------+-----+------------+----------------+


 dbNEW.entity
 +--------------+---------------------+------+-----+------------+----------------+
 | Field        | Type                | Null | Key | Default    | Extra          |
 +--------------+---------------------+------+-----+------------+----------------+
 | entityID     | int(10) unsigned    | NO   | PRI | NULL       | auto_increment |
 | commonName   | varchar(20)         | NO   |     |            |                |
 | surname      | varchar(20)         | NO   |     |            |                |
 +--------------+---------------------+------+-----+------------+----------------+

我为什么要这样做?基本上,我有一个“商店”实体,它将具有“用户”公用的字段,例如地址和电话号码。因此,任何“
ENTITY”都可能没有多个地址(送货,帐单,邮寄),也没有多个电话号码(传真,主,帐单,手机,家),可能有其他方法可以做到这一点,但这是我的解决方案最后。

旧数据库中的商店和用户需要保留其旧PK,并获得额外的ENTITY fk。如何在不进行转储和手动编辑的情况下执行此操作?


阅读 206

收藏
2021-05-10

共1个答案

admin

对于最后一个查询,请使用此

INSERT INTO dbNEW.`user` (userID, entityID, other)  
SELECT user_id, entityID, other
FROM
(
    SELECT user_id, @key + @rn entityID, other, @rn := @rn + 1
    FROM (select @rn:=0) x, dbOLD.`user`
    order by user_id
) y;

MySQL中的LAST_INSERT_ID()是成批创建的第一个ID,与SQL Server中的SCOPE_IDENTITY()不同,后者是LAST
ID。由于它是第一行,因此我们使用变量@rn从addition=0第一行开始递增每一行。

2021-05-10