SQL Server将自动增量主键添加到现有表


253

作为标题,我有一个现有表,该表已经填充了150000条记录。我添加了一个ID列(当前为null)。

我假设我可以运行查询以用增量数字填充此列,然后将其设置为主键并启用自动增量。这是正确的进行方式吗?如果是这样,我该如何填写初始数字?

Answers:


429

否-您必须采用另一种方法:从一开始INT IDENTITY就将其添加-执行此操作时,它将被标识值填充:

ALTER TABLE dbo.YourTable
   ADD ID INT IDENTITY

然后可以将其设为主键:

ALTER TABLE dbo.YourTable
   ADD CONSTRAINT PK_YourTable
   PRIMARY KEY(ID)

或者,如果您希望一步一步完成所有操作:

ALTER TABLE dbo.YourTable
   ADD ID INT IDENTITY
       CONSTRAINT PK_YourTable PRIMARY KEY CLUSTERED

2
这是一个很好的答案,但是如何将起始整数从1更改为1000?我想从1000开始计数。我怀疑我可以使用,ALTER TABLE ORDER ALTER COLUMN ORDERNO RESTART WITH 1但我不想在没有专家检查的情况下尝试使用它:) pic.dhe.ibm.com/infocenter/iseries/v7r1m0/…– 2013
user1477388

3
我只是使用了它,它似乎已经起作用了alter table attachments add ATTACHMENT_NUMBER int identity (1000, 1)
user1477388 2013年

1
@stom:如果您未指定任何内容,则将使用seed = 1和增量= 1-无论如何这是最常用的设置。如果您创建了这样的表格-它就可以正常工作。但是我建议始终在您的SQL脚本中明确指定种子和增量-特别是对于较大的站点。这只是个好习惯。
marc_s 2015年

1
@stom:好吧,这PRIMARY KEY意味着NOT NULL到位-再说一次-这不是绝对必要的。但是我更愿意讲清楚,所以我总是在NOT NULL那里,只是要绝对清楚
marc_s 2015年

3
@ turbo88:当你定义PRIMARY KEY,聚集索引会自动为您创建(除非你明确指定NONCLUSTERED
marc_s

19

您无法“打开”身份:这是表重建。

如果您不关心数字顺序,则可以一次性添加IDENTITY的NOT NULL列。15万行不是很多。

如果需要保留一些数字顺序,则相应地添加数字。然后,使用SSMS表设计器设置IDENTITY属性。这使您可以生成一个脚本,该脚本将为您执行列删除/添加/保留数字/种子设置。


5
OP在SQL Server 2008上运行,因此有一种方法
Martin Smith,

整个实例需要在单用户模式下启动,因此在大多数情况下可能不可行,但ALTER TABLE ... SWITCH如果没有这样做就可以做到。
马丁·史密斯

11

我遇到了这个问题,但由于种种原因无法使用身份列。我解决了这个问题:

DECLARE @id INT
SET @id = 0 
UPDATE table SET @id = id = @id + 1 

这里借来的。


4

如果表中已经存在该列,并且该列为null,则可以使用以下命令(替换ID,表名和tablekey)更新该列:

UPDATE x
SET x.<Id> = x.New_Id
FROM (
  SELECT <Id>, ROW_NUMBER() OVER (ORDER BY <tablekey>) AS New_Id
  FROM <tablename>
  ) x

你用这个节省了我的时间!@gbn的答案的很好的附录。
克里斯汀·怀特

2

当我们在现有表中添加和标识列时,它将自动填充,而无需手动填充。


2

由设计人员,您可以设置身份(1,1),在tbl => desing =>上单击鼠标左键(右键单击)=>属性=>在身份列中选择#column

物产

身份栏


1
您是否知道这是否是一种好方法?OP正在询问这是否是“正确的进行方式”。更加完整的答案可以帮助他们了解该方法的优缺点。
jinglesthula

确实,我在开发环境中正在使用此选项,如果您将此更改传递给生产,如果某些存储过程或触发器正在使用标识字段,则应使用VIEW DEPENDENCY进行验证。
gustavo herrera

2

如果您的表使用其主键或外键与其他表有关系,则可能无法更改您的表。因此您需要删除并再次创建表。
要解决这些问题,您需要通过右键单击数据库并在高级选项中将数据类型设置为脚本以编写方案和数据来生成脚本。之后,将此脚本与更改您的列一起使用,以通过运行其查询来标识并重新生成该表。
您的查询将如下所示:

USE [Db_YourDbName]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
Drop TABLE [dbo].[Tbl_TourTable]

CREATE TABLE [dbo].[Tbl_TourTable](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](50) NULL,
    [Family] [nvarchar](150) NULL)  

GO

SET IDENTITY_INSERT [dbo].[Tbl_TourTable] ON 

INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')
INSERT [dbo].[Tbl_TourTable] ([ID], [Name], [Family]) VALUES (1,'name 1', 'family 1')

SET IDENTITY_INSERT [dbo].[Tbl_TourTable] off 

0

这是您可以尝试的想法。原始表-没有标识列table1创建一个新表-与标识列一起调用table2。将数据从表1复制到表2-标识列将自动填充自动递增的数字。

将原始表重命名为table1到table3将新表重命名为table2到table1(原始表)现在,您已经有了包含标识列的table1并填充了现有数据。确保没有问题并能正常工作后,在不再需要时放下table3。


0

创建一个具有不同名称和相同列,主键和外键关联的新表,并将其链接到您的代码插入语句中。例如:对于雇员,请替换为雇员。

CREATE TABLE EMPLOYEES(

    EmpId        INT NOT NULL IDENTITY(1,1), 
    F_Name       VARCHAR(20) ,
    L_Name       VARCHAR(20) ,
    DOB          DATE ,
    DOJ          DATE ,
    PRIMARY KEY (EmpId),
    DeptId int FOREIGN KEY REFERENCES DEPARTMENT(DeptId),
    DesgId int FOREIGN KEY REFERENCES DESIGNATION(DesgId),
    AddId int FOREIGN KEY REFERENCES ADDRESS(AddId)   
) 

但是,您必须删除现有的EMPLOYEE表或根据需要进行一些调整。


0

该答案是投票最高的答案的一个很小的补充,适用于SQL Server。该问题要求自动递增主键,当前答案的确添加了主键,但未将其标记为自动递增。下面的脚本检查列是否存在,并在启用了autoincrement标志的情况下添加它。

IF NOT EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'YourTable' AND COLUMN_NAME = 'PKColumnName')
BEGIN


ALTER TABLE dbo.YourTable
   ADD PKColumnName INT IDENTITY(1,1)

CONSTRAINT PK_YourTable PRIMARY KEY CLUSTERED

END

GO

0
ALTER TABLE table_name ADD temp_col INT IDENTITY(1,1) 
update 

5
你能解释一下吗?
Muhammad Dyas Yaskur

1
尽管此代码可以解决OP的问题,但最好包含有关您的代码如何解决OP的问题的说明。这样,将来的访问者可以从您的帖子中学习,并将其应用于自己的代码。SO不是编码服务,而是知识资源。而且,更可能会推荐高质量,完整的答案。这些功能,以及所有职位必须自成体系的要求,是SO作为平台的强项,可以将其与论坛区分开。您可以进行编辑以添加其他信息和/或在源文档中补充说明。
ysf

-1

alter table / **粘贴表格名称** /添加id int IDENTITY(1,1)

从/ **删除,粘贴表格名称** /,其中id为

选择a.id FROM / **粘贴制表符的名称/作为左外连接(SELECT MIN(id)as id FROM /粘贴制表符的名称/ GROUP BY / 粘贴列c1,c2 .... ** /

) as t1 
ON a.id = t1.id

t1.id为NULL的位置

修改表/ **粘贴表格名称** / DROP COLUMN ID


你有什么问题?怎么问
安·基尔泽

1
使用markdown编辑您的答案,以正确设置代码示例的格式。
比尔·凯勒

-3

尝试这样的事情(首先在测试表上):

使用your_database_name
走
(从your_table中选择COUNT(*),而your_id_field为NULL)> 0
开始
    设置行数1
    更新your_table SET your_id_field = MAX(您的id_field)+1
结束
打印“全部完成”

我根本没有测试过,所以要小心!


1
-1不回答问题(与添加IDENTITY列有关),无论如何都不起作用。UPDATE your_table SET your_id_field = MAX(your_id_field)+1你不能只是卡在MAX那儿。WHERE避免重复更新同一行的子句在哪里?
马丁·史密斯,

-3

这在MariaDB中有效,所以我只能希望它在SQL Server中有效:删除刚刚插入的ID列,然后使用以下语法:

ALTER TABLE table_name添加ID INT主键AUTO_INCREMENT;

不需要另一个表。这只是插入一个id列,使其成为主索引,并使用顺序值填充它。如果SQL Server无法做到这一点,我很抱歉浪费您的时间。


-3

ALTER TABLE table_name添加列ID INT非空主键AUTO_INCREMENT; 这可能很有用

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.