Sql 使用外键从现有数据库更改标识
我犯了两个错误,我真的不知道如何解决它。首先,我在表中插入了一个对象,但标识不是好的标识。它应该是1而不是10 我的第二个错误是,我在表中设置了一些标识为1,1,而不是10,10。但由于我的两个错误都是外键,我真的不知道如何解决这个问题 多谢各位Sql 使用外键从现有数据库更改标识,sql,sql-server,database,Sql,Sql Server,Database,我犯了两个错误,我真的不知道如何解决它。首先,我在表中插入了一个对象,但标识不是好的标识。它应该是1而不是10 我的第二个错误是,我在表中设置了一些标识为1,1,而不是10,10。但由于我的两个错误都是外键,我真的不知道如何解决这个问题 多谢各位 另外,我想知道如何更改这些标识,而不必在其他表中更改,因为它是一个外键。我不认为您是第一个决定使用外键等更改此类内容的人 我通常的方法是非常手动的,但往往是有效的。我喜欢对这类情况进行大量手动监督,而不是编写复杂的代码并希望它能够工作 对于下面的演示,
另外,我想知道如何更改这些标识,而不必在其他表中更改,因为它是一个外键。我不认为您是第一个决定使用外键等更改此类内容的人 我通常的方法是非常手动的,但往往是有效的。我喜欢对这类情况进行大量手动监督,而不是编写复杂的代码并希望它能够工作 对于下面的演示,我假设表T1有一个指向表T2的外键链接,例如,表T1有一个字段T2_Id 主要问题是,您不能只更改T2中的值,例如从1更改为10,因为表T2中不存在该值。第二个问题是表中可能已经存在所需的ID 因此,我采取的广泛做法是: 将T2中的行从原始ID复制到新ID 更新T1中的相关行以引用新的T2_Id 从T2中删除原始行 注释 在try-catch和事务中进行这些更改,以防出现任何错误 我发现先用T2_ID_old和T2_ID_new创建一个临时表很有用 您需要将IDENTITY INSERT T2设置为ON;在插入T2之前,在关闭设置标识插入T2的情况下进行插入; 如果您想要的值已经存在,那么您可能需要执行循环。最简单但最慢的循环是一次执行1次,如果要向上更改值,则首先从最大值开始,以清除该点,以便以后进行更新 一次一行循环的代码示例。请随时更新。也可以随意使用光标,而不是WHILE循环
DECLARE @CurrentT2IdOriginal int
DECLARE @CurrentT2IdNew int
SET @CurrentT2IdOriginal = (SELECT TOP 1 T2_ID_Original FROM #T2_Updates ORDER BY T2_ID_original DESC)
WHILE @CurrentT2IdOriginal IS NOT NULL
BEGIN
BEGIN TRY
BEGIN TRANSACTION
SET @CurrentT2IDNew = (SELECT TOP 1 T2_ID_New FROM #T2_Updates WHERE T2_ID_original = @CurrentT2IdOriginal)
SET IDENTITY_INSERT T2 ON;
INSERT INTO T2 (ID, randomtext)
SELECT @CurrentT2IdNew, randomtext
FROM T2
WHERE T2.ID = @CurrentT2IdOriginal
SET IDENTITY_INSERT T2 OFF;
UPDATE T1 SET T2_ID = @CurrentT2IdNew WHERE T2_ID = @CurrentT2IdOriginal
DELETE FROM T2 WHERE Id = @CurrentT2IdOriginal
SET @CurrentT2IdOriginal = (SELECT TOP 1 T2_ID_Original FROM #T2_Updates WHERE T2_ID_Original < @CurrentT2IdOriginal ORDER BY T2_ID_original DESC)
COMMIT TRANSACTION
END TRY
BEGIN CATCH
IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;
THROW;
END CATCH
END
这里有一个完整的例子
注意-在过程中的某个时刻,您还需要将ID字段从identity1,1更改为identity10,10
重要的
首先在测试站点上执行此操作。
事后检查数据,以防在执行此操作时有人插入了更多行。