从另一个表中复制 IDENTITY 列并为丢失的记录生成新的 ID
Posted
技术标签:
【中文标题】从另一个表中复制 IDENTITY 列并为丢失的记录生成新的 ID【英文标题】:Copy IDENTITY column from another table and generate new IDs for missing records 【发布时间】:2021-11-14 20:46:28 【问题描述】:我正在尝试将标识列从一个表复制到另一个表,但出现此错误:
无法更新身份列“ID”。
我尝试了以下代码:
ALTER TABLE [dbo].[TableA]
ADD [ID] INT IDENTITY(20000,1), -- MAX(TableB.Id) < 20000
SET IDENTITY_INSERT TableA ON
UPDATE TableA
SET TableA.[ID] = TableB.[ID]
FROM TableA
INNER JOIN TableB ON TableB.ID = TableA.ID
SET IDENTITY_INSERT TableA OFF;
场景
我有两个 1:0-1 关系的表。
TableA: Code (PK)
A,
B,
C,
D
TableB: Id (PK), Code (Unique)
1, A
2, B
3, D
问题
如何
-
创建新的标识列
TableA.Id
从TableB.Id
复制值
如果TableB.Id
中缺少TableA.Id
,请确保它的新唯一值
【问题讨论】:
正如错误告诉你的那样,你不能UPDATE
IDENTITY
的值。您需要CREATE
一个新表,并将INSERT
数据放入启用IDENTITY_INSERT
的新表中。然后你可能想DROP
你的旧表,并重命名你的新表。
dbfiddle.uk/…
外键约束有很多需要考虑的地方。见***.com/questions/1049210/…。另外,没有涉及的行数。在这些情况下,需要通过一个侧表,替换外键约束,删除旧表并将新表(sp_)重命名为旧表。恐怕这很乏味。
【参考方案1】:
=不是原始问题的真正答案,请参阅评论=
您不能更新本身就是您的加入条件的列。这是行不通的。
保持标识列完整的最安全方法是先从表 A 中的表 B 中删除行。 然后只需在 IDENTITY_INSERT ON 的情况下从表 B 插入表 A。 此外,这假设表 A 和表 B 共有的行之间存在 1:1 的关系。表 A 和表 B 之间的 1:0-1 关系意味着您需要从表 A 中的表 B 中捕获 ID 作为外键关系如果这会导致表 A 中的结果为 NULL,则改为单独列。
简而言之(伪代码),假设行之间的关系为 1:1:
DELETE FROM Table A WHERE Key EXISTS IN (SELECT Key FROM Table B)
;
SET IDENTITY_INSERT Table A ON
;
INSERT INTO Table A
( id_column, [other_columns [, othercolumns] ] )
SELECT
id_column, [other_columns [, othercolumns] ]
FROM Table B
;
SET IDENTITY_INSERT Table A OFF
;
【讨论】:
第一眼看起来不错,但 DELETE 不起作用,因为我有很多 FK 指向 TableA。以上是关于从另一个表中复制 IDENTITY 列并为丢失的记录生成新的 ID的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 join codeigniter 从另一个表中获取值
PostgreSQL - 从连接表中选择聚合列并使用它来求和