错误后重新插入/更新主键值(恢复)[重复]

Re-Insert/Update primary key value after a mistake (restoration) [duplicate]

提问人:Maxime 提问时间:11/15/2023 最后编辑:marc_sMaxime 更新时间:11/15/2023 访问量:42

问:

我在 SQL Server 中遇到了问题。

我们有一个表作为其主键。请注意,该表大约有 10 列,但我只显示以下两列作为示例:CountryN_Country

N_Country 名字
1 英国
2 西班牙
3 法国
4 德国
5 意大利

但是,我们不知道为什么,但第三行(法国)被删除了。现在,我们只有主键 1/2/4/5,不再是 3。

我不能在此表中添加一行,因为它会使一个主键为 6 的国家/地区,因为我需要将所有其他具有“N = 3”的表更新为“N = 6”,这是一项繁重的工作(而且我“不知道所有需要更新的表”)。

我看到的“最快/最佳”的两个解决方案是:

  1. 我创建一个新行(N = 6,名称 = 法国),然后我

     UPDATE Country
     SET N_Country = 3 
     WHERE N_Country = 6
    
  2. 我直接做

     INSERT INTO Country (N_Country, Name) 
     VALUES (3, 'France')
    

两者都应该是“安全的”,因为我只是在恢复已删除的值。我从不更新主键(因为这是一个非常糟糕的主意),但在这里我遇到了错误

IDENTITY_INSERT定义为 OFF

我从相关帖子中看到SET IDENTITY_INSERT aTable ON

我想知道我是否可以使用这样的东西?

SET IDENTITY_INSERT Country ON
GO

-- Attempt to insert an explicit ID value of 3
INSERT INTO Country (N_Country, Name) 
VALUES (3, 'France')
GO

SET IDENTITY_INSERT aTable OFF
GO

而且,如果您认为这是“安全的”?(我猜是这样) - 但是,如果我的表 Country 有 10 列,我应该“插入”所有 10 列,还是可以只插入两个主要列,然后稍后更新?

谢谢你的帮助。

sql sql-server sql-update sql-insert 主键

评论

1赞 Mitch Wheat 11/15/2023
你测试时发生了什么?
0赞 Maxime 11/15/2023
当我尝试插入时,我收到错误“IDENTITY_INSERT定义为关闭” 当我尝试更新主键时,我收到一个错误“无法更新主键”
3赞 siggemannen 11/15/2023
标识插入方法应该有效。您无法更新标识字段
1赞 Dan Guzman 11/15/2023
问题中的脚本应该可以重新插入该行,其他列可以在以后更新。该错误表明语句未在同一会话/连接上运行。
0赞 Maxime 11/15/2023
谢谢大家。我只是想确保它是安全的,所以一切都很好,它正在工作:)有好的一天!

答:

1赞 Knut Boehnert 11/15/2023 #1

如果要在标识列上插入特定值,则首先

SET IDENTITY_INSERT <schema>.<table> ON;

这允许使用后续 insert 语句为 identity 列插入所需的值。

之后非常重要:

SET IDENTITY_INSERT <schema>.<table> OFF;

数据库中的所有表一次只能存在一个 ON 状态。

1赞 Fenton 11/15/2023 #2

您可以使用此技术仅插入缺少的记录。

您需要确保您的语句匹配 - 在您的示例中,您将其设置为 ,但将其切换为 。这将使表上的标识插入处于打开状态。INDENTITY_INSERTONCountryOFFaTableCountry

SET IDENTITY_INSERT Country ON
INSERT INTO Country (N_Country, Name) VALUES (3, 'France') 
SET IDENTITY_INSERT Country OFF

使用架构进行测试

CREATE TABLE Country(
  N_Country INT IDENTITY(1,1) PRIMARY KEY,
  Name NVARCHAR(100)
)