如何以编程方式更改标识列值?

我有一个 MSSQL2005数据库与一个表 Test与列 IDID是一个身份列。

这个表中有一些行,它们都有相应的 ID 自动递增值。

现在我要像下面这样更改表中的每个 ID:

ID = ID + 1

但是当我这样做的时候,我得到了一个错误:

无法更新标识列“ ID”。

我试过了:

    ALTER TABLE Test NOCHECK CONSTRAINT ALL
set identity_insert ID ON

但这并不能解决问题。

我需要将标识设置为这个列,但是我也需要不时地更改值。所以我的问题是如何完成这项任务。

324581 次浏览

通过 SQLServer2005管理器中的 UI,更改该列,删除该列的 autonumber (Identity)属性(右键单击该表并选择“ Design”)。

然后运行你的查询:

UPDATE table SET Id = Id + 1

然后将 autonumber 属性添加回列。

如果该列不是 PK,那么您总是可以在表中创建一个新列,其中包含递增的数字,删除原始列,然后将新列改为旧列。

我很好奇为什么需要这样做... ... 我用 Identity 列做的最多的事情就是回填数字,最后我使用的是 DBCC CHECKIST (tablename,RESEED,newnextnumber)

祝你好运!

身份修改可能会失败,这取决于许多因素,主要围绕与 id 列链接的对象/关系。看起来数据库设计在这里是个问题,因为 id 应该很少发生变化(我相信您有自己的理由,并且正在逐级转换这些变化)。如果您真的需要不时地更改 id,我建议您创建一个新的虚拟 id 列,它不是您可以管理自己并从当前值生成的主键/自动编号。另外,基督徒的想法上面将是我的另一个建议,如果你有问题,允许身份插入。

祝你好运

PS 它没有失败是因为它运行的顺序是尝试将列表中的值更新为 id 列表中已经存在的项?抓住最后一根稻草,也许加上行的数目 + 1,如果这样做有效,那么减去行的数目:-S

首先,IDENTITY _ INSERT 的开或关设置不能满足您的需要(它用于插入新值,比如堵塞间隙)。

通过 GUI 执行操作只需创建一个临时表,将所有数据复制到一个没有标识字段的新表中,然后重命名该表。

如果偶尔需要更改 ID,最好不要使用标识列。在过去,我们使用“计数器”表手动实现自动编号字段,该表跟踪每个表的下一个 ID。IIRC 我们这样做是因为标识列导致 SQL2000中的数据库损坏,但是能够更改 ID 对于测试偶尔是有用的。

你必须这么做

set identity_insert YourTable ON

然后删除您的行并重新插入不同的标识。

插入完成后,不要忘记关闭 Identity _ insert

set identity_insert YourTable OFF

DBCC CHECKIST (‘ database asename.dbo.orders’,RESEED,999) 你可以用这个命令改变任何标识列号,你也可以从你想要的每个数字开始这个字段号。例如,在我的命令中,我要求从1000(999 + 1)开始 希望这样就够了... 祝你好运

这可以通过使用临时表来完成。

这个想法

  • 禁用约束(以防您的 id 被外键引用)
  • 用新的 id 创建一个临时表
  • 删除表格内容
  • 将数据从复制的表复制回原始表
  • 启用先前禁用的约束

SQL 查询

假设您的 test表有两个额外的列(column2column3) ,并且有两个表具有引用 test的外键,称为 foreign_table1foreign_table2(因为现实生活中的问题从来都不简单)。

alter table test nocheck constraint all;
alter table foreign_table1 nocheck constraint all;
alter table foreign_table2 nocheck constraint all;
set identity_insert test on;


select id + 1 as id, column2, column3 into test_copy from test v;
delete from test;
insert into test(id, column2, column3)
select id, column2, column3 from test_copy


alter table test check constraint all;
alter table foreign_table1 check constraint all;
alter table foreign_table2 check constraint all;
set identity_insert test off;
drop table test_copy;

就是这样。

我在最后一刻看到了一篇帮助我的好文章。.我试图在一个有标识列的表中插入几行,但是插错了,不得不删除回来。一旦我删除了这些行,我的身份列就会发生变化。我试图找到一种方法来更新插入的专栏,但没有运气。因此,当在谷歌上搜索时,发现了一个链接。.

  1. 删除错误插入的列
  2. 使用强制插入使用标识打开/关闭(解释如下)

Http://beyondrelational.com/modules/2/blogs/28/posts/10337/sql-server-how-do-i-insert-an-explicit-value-into-an-identity-column-how-do-i-update-the-value-of-an.aspx

IDENTITY列值是不可变的。

但是,可以切换表元数据以删除 IDENTITY属性,执行更新,然后切换回来。

假设以下结构

CREATE TABLE Test
(
ID INT IDENTITY(1,1) PRIMARY KEY,
X VARCHAR(10)
)


INSERT INTO Test
OUTPUT INSERTED.*
SELECT 'Foo' UNION ALL
SELECT 'Bar' UNION ALL
SELECT 'Baz'

然后你就可以

/*Define table with same structure but no IDENTITY*/
CREATE TABLE Temp
(
ID INT PRIMARY KEY,
X VARCHAR(10)
)


/*Switch table metadata to new structure*/
ALTER TABLE Test SWITCH TO Temp;


/*Do the update*/
UPDATE Temp SET ID = ID + 1;


/*Switch table metadata back*/
ALTER TABLE Temp SWITCH TO Test;


/*ID values have been updated*/
SELECT *
FROM Test


/*Safety check in case error in preceding step*/
IF NOT EXISTS(SELECT * FROM Temp)
DROP TABLE Temp /*Drop obsolete table*/

在 SQLServer2012中,可以有一个自动递增的列,也可以使用 SEQUENCES更直接地进行更新

CREATE SEQUENCE Seq
AS INT
START WITH 1
INCREMENT BY 1


CREATE TABLE Test2
(
ID INT DEFAULT NEXT VALUE FOR Seq NOT NULL PRIMARY KEY,
X VARCHAR(10)
)


INSERT INTO Test2(X)
SELECT 'Foo' UNION ALL
SELECT 'Bar' UNION ALL
SELECT 'Baz'


UPDATE Test2 SET ID+=1

可以插入带有修改值的新行,然后删除旧行。下面的示例将 ID 更改为与外键 是个人相同

SET IDENTITY_INSERT [PersonApiLogin] ON


INSERT INTO [PersonApiLogin](
[Id]
,[PersonId]
,[ApiId]
,[Hash]
,[Password]
,[SoftwareKey]
,[LoggedIn]
,[LastAccess])
SELECT [PersonId]
,[PersonId]
,[ApiId]
,[Hash]
,[Password]
,[SoftwareKey]
,[LoggedIn]
,[LastAccess]
FROM [db304].[dbo].[PersonApiLogin]
GO


DELETE FROM [PersonApiLogin]
WHERE [PersonId] <> ID
GO
SET IDENTITY_INSERT [PersonApiLogin] OFF
GO

很好的问题,首先我们需要 开始特定表的 IDENTITY _ INSERT,然后运行插入查询(必须指定列名)。

注意: 在编辑标识列之后,不要忘记 关掉 IDENTITY _ INSERT。如果没有完成,则无法编辑任何其他表的标识列。

SET IDENTITY_INSERT Emp_tb_gb_Menu ON
INSERT Emp_tb_gb_Menu(MenuID) VALUES (68)
SET IDENTITY_INSERT Emp_tb_gb_Menu OFF

Http://allinworld99.blogspot.com/2016/07/how-to-edit-identity-field-in-sql.html

首先保存所有 ID,并用编程方式将它们修改为不需要的值,然后从数据库中删除它们,然后使用类似的方法再次插入它们:

use [Name.Database]
go
set identity_insert [Test] ON
insert into [dbo].[Test]
([Id])
VALUES
(2)
set identity_insert [Test] OFF

用于批量插入:

use [Name.Database]
go
set identity_insert [Test] ON
BULK INSERT [Test]
FROM 'C:\Users\Oscar\file.csv'
WITH (FIELDTERMINATOR = ';',
ROWTERMINATOR = '\n',
KEEPIDENTITY)
set identity_insert [Test] OFF

来自 file.csv 的示例数据:

2;
3;
4;
5;
6;

如果你没有设置 identity_insert为 off,你会得到下面的错误:

时,无法为表“ Test”中的标识列插入显式值 IDENTITY _ INSERT 设置为 OFF。