更新自增列中的值

36

我怎样在 MSSQL 中覆盖 identity 列?我尝试了:

    SET IDENTITY_INSERT GeoCountry ON
    UPDATE GeoCountry SET CountryID = 18 WHERE CountryID = 250

但是我得到了以下结果:

第二行:无法更新标识列'CountryID'。

5个回答

69
你正在尝试进行更新,而不是插入新行。
为了实现这一点,你需要将 identity_insert 设置为ON,并将要更新的行复制到一个新的具有新ID值的行中,然后删除旧行(假设没有任何外键引用该行)。
大致上说,应该像这样做:
set identity_insert GeoCountry on
go

insert into GeoCountry (all columns including IDentity column) 
     select 18, (all columns except IDentity column)
     from GeoCountry where CountryID = 250 

-- Delete will only work if no referencing FK's
delete GeoCountry where CountryID = 250

set identity_insert GeoCountry off
go
[鉴于你试图更新它,这说明它仍在使用中(即通过引用FK),这使事情变得更加复杂...]

1
对我来说也起作用了,但括号中的部分一开始有些令人困惑。因此,为了更加精确:插入到GeoCountry(column1,column2,columnN)中 选择18,column2,columnN 来自GeoCountry的where CountryID = 250 - Laminar

12

在SQL Server中,无法更新身份列。您必须删除原始记录,然后使用身份值插入记录,因为没有支持更新身份值的功能。

打开[ColumnName]标识插入 插入先前存储在该记录中的标识和其他信息 关闭[ColumnName]标识插入


2
+1 我认为这是正确的答案。当面临“如何更新标识值”的问题时,重要的细节是您实际上不能更新该值,而必须删除并重新插入。接受的答案在这方面失败了。 - alan

10

如果你想要更新一个身份列,这里提供一种可能的方法:

  • 在 SQL Server Management Studio 中,打开表格的设计视图,在该列上禁用 "Identity Specification > Is Identity"
  • 执行更新
  • 启用 "Identity Specification > Is Identity" 该列

使用 SELECT IDENT_CURRENT('<table name>') 来查看当前表中存在的最高 id。


如果您有具有级联更新的外键,那么这种方法是更好的选择,因为您可以“免费”获得更新。 - Jacob

5
您也可以使用“delete into”在一条语句中完成此操作,这样做的好处是消除了复制/移动行数据时可能出现的任何错误,例如:
set identity_insert [dbo].[MyTableName] on

delete from [dbo].[MyTableName]
output 
<new-id-value-here>,
[deleted].[Col1], 
[deleted].[Col2], 
[deleted].[Col3], 
into 
[dbo].[MyTableName] (
[IdColumnName], 
[Col1], 
[Col2], 
[Col3])
where
[IdColumnName]=<old-id-value-here>

set identity_insert [dbo].[MyTableName] off

0

如果您想重新枚举标识字段的值,因为例如这些值已经混乱了,只需按照以下步骤操作:

  • 在设计模式下打开表格

    单击“标识规范”

    将“(是标识)”标记为“否”

    (您的标识字段仍然是主键)

    关闭并保存设计

  • 在编辑模式下打开表格

    根据需要更改标识字段的值

    (只需注意不能有重复值)

  • 关闭表格,再次在设计模式下打开它

    将标识字段(是标识)替换为“是”

    关闭表格,完成。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接