ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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


m
marc_s

不 - 你必须反过来做:从一开始就将它添加为 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

这是一个非常好的答案,但是如何将起始整数从 1 更改为 1000?我想从 1000 开始数。我怀疑我可以使用 ALTER TABLE ORDER ALTER COLUMN ORDERNO RESTART WITH 1 但我不想在没有与专家核实的情况下尝试它:) 参考。 pic.dhe.ibm.com/infocenter/iseries/v7r1m0/…
我刚用过它,它似乎有效alter table attachments add ATTACHMENT_NUMBER int identity (1000, 1)
@stom:如果您不指定任何内容,则将使用 seed=1 和 increment=1 - 这是最常用的设置。如果您创建了这样的表 - 它会正常工作。但我建议始终在 SQL 脚本中明确指定种子和增量——尤其是对于较大的站点。这只是一个好习惯。
@stom:嗯,PRIMARY KEY 暗示 NOT NULL 已经到位 - 再说一遍 - 这不是绝对必要的。但我更喜欢显式,所以我总是有 NOT NULL,只是为了绝对清楚
@turbo88:当您定义 PRIMARY KEY 时,会自动为您创建聚集索引(除非您明确指定 NONCLUSTERED
g
gbn

您不能“打开” IDENTITY:它是表重建。

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

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


OP 在 SQL Server 2008 so there is a way
整个实例需要在单用户模式下启动,因此在大多数情况下可能不可行,但 ALTER TABLE ... SWITCH 可以做到这一点。
K
Kevin

我遇到了这个问题,但无法使用标识列(出于各种原因)。我解决了这个问题:

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

here 借来的。


R
Renzo Ciot

如果该列已存在于您的表中并且为空,您可以使用此命令更新该列(替换 id、tablename 和 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 的答案很好的附录。
u
user3279092

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


K
KJN

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

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

很遗憾,帖子上有很多赞成票,你的回答对我来说是 100%,希望我能添加更多赞成票
g
gustavo herrera

设计师可以设置身份(1,1)右键单击tbl =>设计=>部分左(右键单击)=>属性=>在身份列中选择#column

Properties

idendtity column


你有关于这是否是一个好方法的信息吗? OP正在询问这是否是“正确的继续方式”。更完整的答案可以帮助他们了解该方法的优缺点。
真的,我在开发环境中使用了这个选项,如果你想把这个更改传递给生产环境,你应该使用 VIEW DEPENDENCY 验证身份字段是否被某些存储过程或触发器使用。
C
Community
ALTER TABLE table_name ADD temp_col INT IDENTITY(1,1) 
update 

你能解释一下吗?
虽然此代码可能会解决 OP 的问题,但最好包括说明您的代码如何解决 OP 的问题。通过这种方式,未来的访问者可以从您的帖子中学习,并将其应用到他们自己的代码中。 SO 不是编码服务,而是知识资源。此外,高质量、完整的答案更有可能得到支持。这些功能,以及所有帖子都是独立的要求,是 SO 作为一个平台的一些优势,使其与论坛区分开来。您可以编辑以添加其他信息和/或使用源文档补充您的解释。
我通过谷歌搜索到达这里,因为我只需要语法。这对我来说是最好的答案,可能还有很多其他没有 SO 帐户的人。我忽略了接受的答案,因为它太长了!我的观点是,有两种类型的访问者——一种寻找完整的解释,另一种使用 SO 作为快速参考。有用的是具有 TLDR 部分的答案。
H
Hamid

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

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 

J
JH326

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

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


R
Roman Marusyk

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

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 表或根据您的要求进行一些调整。


M
Mohamed Sakilani

alter table /** 粘贴 tabal 的名字 **/ add id int IDENTITY(1,1)

delete from /** 粘贴 tabal 的名字 **/ where id in

(

select a.id FROM /** 粘贴 tabal 的名称 / 作为 LEFT OUTER JOIN ( SELECT MIN(id) as id FROM / 粘贴 tabal 的名称 / GROUP BY / 粘贴列 c1,c2 .... **/

) as t1 
ON a.id = t1.id

哪里 t1.id 为空

)

alter table /** 粘贴 tabal 的名字 **/ DROP COLUMN id


你有什么问题? How to ask
编辑您的答案,使用降价来正确格式化您的代码示例。
M
Mahmoud abo ghanam

试试下面的代码:

DBCC CHECKIDENT ('settings', RESEED, 0) 

P
PacDemon

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

USE your_database_name
GO
WHILE (SELECT COUNT(*) FROM your_table WHERE your_id_field IS NULL) > 0
BEGIN
    SET ROWCOUNT 1
    UPDATE your_table SET your_id_field = MAX(your_id_field)+1
END
PRINT 'ALL DONE'

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


-1 不回答问题(关于添加 IDENTITY 列)并且无论如何都不会工作。 UPDATE your_table SET your_id_field = MAX(your_id_field)+1 你不能只是把 MAX 扔在那里。避免重复更新同一行的 WHERE 子句在哪里?
R
Road Warrior

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

ALTER TABLE table_name ADD id INT PRIMARY KEY AUTO_INCREMENT;

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


K
Killer

ALTER TABLE table_name ADD COLUMN ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT ;这可能很有用