使用版本:
Microsoft SQL Server 2008 R2 (SP3-OD) (KB3144114) - 10.50.6542.0 (Intel X86)
Feb 22 2016 18:12:09
Copyright (c) Microsoft Corporation
Standard Edition on Windows NT 5.2 <X86> (Build : )
我有一张沉重的桌子(135K行),我从另一个DB移动了。
它转移时[id]
列是标准int
列,而不是关键字&amp;种子栏。
当尝试编辑该字段以成为身份规范时,使用种子值,其错误输出并给我这个错误:
Execution Timeout Expired.
The timeout period elapsed prior to completion of the operation...
我甚至尝试删除该列,稍后尝试重新创建它,但我得到同样的问题。
由于
更新
表格结构:
CREATE TABLE [dbo].[tblEmailsSent](
[id] [int] IDENTITY(1,1) NOT NULL, -- this is what it should be. currently its just an `[int] NOT NULL`
[Sent] [datetime] NULL,
[SentByUser] [nvarchar](50) NULL,
[ToEmail] [nvarchar](150) NULL,
[StudentID] [int] NULL,
[SubjectLine] [nvarchar](200) NULL,
[MessageContent] [nvarchar](max) NULL,
[ReadStatus] [bit] NULL,
[Folder] [nvarchar](50) NULL,
CONSTRAINT [PK_tblMessages] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
答案 0 :(得分:3)
我认为您的问题与Adding an identity to an existing column重复。上面的问题有answer,应该适合您的情况。我将在下面重现其重要部分。
但在此之前,让我们澄清为什么你会看到超时错误。
您正尝试将IDENTITY
属性添加到现有列。你正在使用SSMS GUI。一个简单的ALTER COLUMN
语句不能这样做,即使可以,SSMS也会生成一个创建新表的脚本,将数据复制到新表中,删除旧表并将新表重命名为旧表名称。当您通过SSMS GUI执行此操作时,它会以30秒的预定义超时运行其脚本。
当然,您可以在SSMS中更改此设置并增加超时,但有更好的方法。
使用SSMS GUI更改列定义,但不是单击“保存”,而是单击表设计器中的“生成更改脚本”。
然后将此脚本保存到文件中,并查看GUI在场景后运行的生成的T-SQL代码。
您将看到它创建了一个包含所需模式的临时表,复制数据,重新创建外键和索引,删除旧表并重命名新表。
脚本本身通常是正确的,但要密切关注其中的事务。由于某种原因,SSMS通常不会对整个操作使用单个事务,而是使用多个事务。我建议您手动查看脚本,确保顶部只有一个BEGIN TRANSACTION
,最后一个COMMIT
。您不希望最终使用半完成操作,例如,删除所有索引和外键的表。
如果是一次性操作,对您来说就足够了。你的桌子只有2.4GB,所以可能需要几分钟,但不应该是几个小时。
如果您在SSMS中自己运行T-SQL脚本,则默认情况下不会超时。如果花费太长时间,你可以自己停止。
主要思想是使用ALTER TABLE...SWITCH
语句使更改仅触及元数据而不触及表格的每一页。
BEGIN TRANSACTION;
-- create a new table with required schema
CREATE TABLE [dbo].[NEW_tblEmailsSent](
[id] [int] IDENTITY(1,1) NOT NULL,
[Sent] [datetime] NULL,
[SentByUser] [nvarchar](50) NULL,
[ToEmail] [nvarchar](150) NULL,
[StudentID] [int] NULL,
[SubjectLine] [nvarchar](200) NULL,
[MessageContent] [nvarchar](max) NULL,
[ReadStatus] [bit] NULL,
[Folder] [nvarchar](50) NULL,
CONSTRAINT [PK_tblEmailsSent] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
-- switch the tables
ALTER TABLE [dbo].[tblEmailsSent] SWITCH TO [dbo].[NEW_tblEmailsSent];
-- drop the original (now empty) table
DROP TABLE [dbo].[tblEmailsSent];
-- rename new table to old table's name
EXEC sp_rename 'NEW_tblEmailsSent','tblEmailsSent';
COMMIT;
新表具有IDENTITY
属性后,通常应将当前标识值设置为表中实际值的最大值。如果不这样做,插入表中的新行将从1开始。
一种方法是在切换表后运行DBCC CHECKIDENT
:
DBCC CHECKIDENT('dbo.tblEmailsSent')
或者,您可以在表定义中指定新种子:
CREATE TABLE [dbo].[NEW_tblEmailsSent](
[id] [int] IDENTITY(<max value of id + 1>, 1) NOT NULL,