Sql 使用外键从现有数据库更改标识

Sql 使用外键从现有数据库更改标识,sql,sql-server,database,Sql,Sql Server,Database,我犯了两个错误,我真的不知道如何解决它。首先,我在表中插入了一个对象,但标识不是好的标识。它应该是1而不是10 我的第二个错误是,我在表中设置了一些标识为1,1,而不是10,10。但由于我的两个错误都是外键,我真的不知道如何解决这个问题 多谢各位 另外,我想知道如何更改这些标识,而不必在其他表中更改,因为它是一个外键。我不认为您是第一个决定使用外键等更改此类内容的人 我通常的方法是非常手动的,但往往是有效的。我喜欢对这类情况进行大量手动监督,而不是编写复杂的代码并希望它能够工作 对于下面的演示,

我犯了两个错误,我真的不知道如何解决它。首先,我在表中插入了一个对象,但标识不是好的标识。它应该是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

重要的

首先在测试站点上执行此操作。 事后检查数据,以防在执行此操作时有人插入了更多行。