如何在SQL Server中给列添加标识(identity)?

11

我有一个大约有1000万行的表格。我们刚用SQL Server Management Studio从另一个数据库导入了它。它创建了表格,但是主键列上没有设置自增和主键。

我可以添加主键,但无法添加自增。当我在设计器中进行操作时,它总是超时。即使我将超时设置为0。

我需要创建另一列来设置主键和自增,然后复制旧数据,删除旧列并重命名新列。

有人能告诉我如何在不额外过热的情况下处理这样大的表格吗?


像这样的东西让你超时了吗?alter table TableName add ID int identity(1, 1) primary key - Tim Lehner
1
你可以使用 ALTER TABLE ... SWITCH 来实现几乎瞬间完成此操作,即使是在一个有1000万行的表上。 - Martin Smith
可能是一个重复问题:如何在创建一个无数据损失的表后设置自动增量? - Martin Smith
@TimLehner:可能不行——他说在可视化设计器中会超时,因为它试图以新格式重新创建表并复制所有数据——总共有1000万行......但使用你的ALTER TABLE语句,应该很容易解决! - marc_s
4个回答

15

无法IDENTITY添加到现有列中。这是不可能的。

你需要创建一个INT IDENTITY类型的列,然后删除你不再需要的旧列(如果需要,可能还需要将新列重命名为旧名称)

另外:我不建议在可视化设计器中进行此操作- 这将尝试使用新结构重新创建表格,复制所有数据(全部1000万行),然后删除旧表格。

使用T-SQL语句会更加高效- 这将进行“原地”更新,非破坏性(不会丢失数据),并且不需要在此过程中复制约10万行...

ALTER TABLE dbo.YourTable
  ADD NewID INT IDENTITY(1,1) NOT NULL

当您向表中添加一个类型为INT IDENTITY的新列时,它将自动填充连续的数字。您无法阻止这种情况发生,也不能在以后更新这些值。

总的来说,这两个选项都不是非常有用 - 您可能最终会得到不同的ID值....要正确地执行此操作,您需要:

  • 预先创建具有正确结构和已设置IDENTITY的新表
  • 然后对该表启用SET IDENTITY_INSERT (yourtable) ON,以允许插入标识列的值
  • 将数据从原始源复制到该表
  • 再次关闭标识插入:SET IDENTITY_INSERT (yourtable) OFF

只有使用这种方法,您才能在新表的ID标识列中获取相同的ID。


1
你可以通过创建一个与原表结构相同但不包含identity属性的新表,将旧表转移到新表中,然后删除旧表并重命名新表的方式,实现向现有列添加identity的目的。这样做可以保持数据页不变。 - Martin Smith
我不同意你的观点。我刚试着在设计模式下给一个有800K行的表添加主键和自增列,结果成功完成了。 - German
@MartinSmith:这也适用于两个非分区表吗?? - marc_s
@Martin Smith:您能澄清一下“将旧表切换到新表”而“保持数据页不变”的意思是什么吗? - Andomar
2
@Andomar - 它只是更改表元数据。不必将所有行复制到新表中或向所有现有行添加列。此处有示例代码 - Martin Smith
1
@German,确实无法向现有表添加标识列。如果您使用了SSMS(或类似的工具),则可能会看起来像您已将其添加到现有表中,但在幕后,新表被创建并导入了行 - 在许多情况下可能是没有区别的区别。 - E.J. Brennan

4
您可以向现有列添加 IDENTITY。这很容易实现。 在 SSMS 中,只需转到工具-->选项-->设计师-->表和数据库设计师,并取消选中防止需要重新创建表的更改的选项。 现在在设计模式下添加所需列的自增属性并保存即可。

4

好的。我已经成功将标识添加到了现有的1000万行主列中,用时约30分钟。

具体步骤如下:

  1. 将数据库更改为单用户模式(确保没有其他连接到数据库,可以引起锁定)

  2. 以设计者模式打开表格

  3. 进行更改。不要保存

  4. 单击生成更改脚本按钮(通常在对象资源管理器上方右侧)

  5. 复制生成的脚本
  6. 关闭设计窗口(一次只能运行一个实例)
  7. 打开新窗口
  8. 执行脚本

  9. 完成。现在您的列已经有了标识 :)


1
请检查脚本。我确信它会创建一个新表,将所有数据复制到新表中,然后删除原始表。 - Bill
1
如果你按照我的链接做的话,30秒就能搞定了! - Martin Smith

2

通过使用选项set identity_insertinsert期间设置identity列是一种方法。例如,要将此表中的id更改为identity

create table YourTable (id int, value varchar(50))

您可以使用这个脚本:
-- Create empty table as a copy of the original
select top 0 * into YourTable_New from YourTable

-- Drop the old ID column
alter table YourTable_New drop column id

-- Add a new ID column with identity
alter table YourTable_New add id int identity

-- Copy the old values into the identity column
set identity_insert YourTable_New on 
insert YourTable_New (id, value) select id, value from YourTable
set identity_insert YourTable_New off

-- Drop the old table and rename the new one
drop table YourTable
exec sp_RENAME 'YourTable_New' , 'YourTable'

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