我需要将表的主键更改为标识列,而且表中已经有了许多行。
我有一个脚本来清理ID以确保它们从1开始连续,测试数据库上运行良好。
如何使用SQL命令更改该列以具有标识属性?
我需要将表的主键更改为标识列,而且表中已经有了许多行。
我有一个脚本来清理ID以确保它们从1开始连续,测试数据库上运行良好。
如何使用SQL命令更改该列以具有标识属性?
无法更改已有列的标识。
你有两个选项,
创建一个带有标识的新表并删除现有表
创建一个带有标识的新列并删除现有列
方法1(新表):在这里,你可以在新创建的标识列上保留现有的数据值。请注意,如果未满足“if not exists”的条件,你将失去所有数据,因此请确保在删除时也加入该条件!
CREATE TABLE dbo.Tmp_Names
(
Id int NOT NULL
IDENTITY(1, 1),
Name varchar(50) NULL
)
ON [PRIMARY]
go
SET IDENTITY_INSERT dbo.Tmp_Names ON
go
IF EXISTS ( SELECT *
FROM dbo.Names )
INSERT INTO dbo.Tmp_Names ( Id, Name )
SELECT Id,
Name
FROM dbo.Names TABLOCKX
go
SET IDENTITY_INSERT dbo.Tmp_Names OFF
go
DROP TABLE dbo.Names
go
Exec sp_rename 'Tmp_Names', 'Names'
方法二 (新增一列) 你无法保留新建标识列上原有的数据值,标识列将会保存数字序列。
Alter Table Names
Add Id_new Int Identity(1, 1)
Go
Alter Table Names Drop Column ID
Go
Exec sp_rename 'Names.Id_new', 'ID', 'Column'
详见下面的微软SQL Server论坛帖子:
CREATE TABLE Test
(
id int identity(1,1),
somecolumn varchar(10)
);
INSERT INTO Test VALUES ('Hello');
INSERT INTO Test VALUES ('World');
-- copy the table. use same schema, but no identity
CREATE TABLE Test2
(
id int NOT NULL,
somecolumn varchar(10)
);
ALTER TABLE Test SWITCH TO Test2;
-- drop the original (now empty) table
DROP TABLE Test;
-- rename new table to old table's name
EXEC sp_rename 'Test2','Test';
-- update the identity seed
DBCC CHECKIDENT('Test');
-- see same records
SELECT * FROM Test;
有一篇TechNet上的文章详细介绍了上述要求。
更新 - Eric Wu在下面发表了一条评论,增加了有关此解决方案的重要信息。在此复制,以确保它获得更多关注:
这里还有一个值得一提的注意事项。虽然新表可以从旧表中接收数据,所有新行将按照标识模式插入,但它们将从1开始,并且如果该列是主键,则可能会出现问题。切换后立即运行DBCC CHECKIDENT('<newTableName>')
。有关更多信息,请参见msdn.microsoft.com/en-us/library/ms176057.aspx。IDENTITY (2435457, 1)
,而不是使用DBCC CHECKIDENT
。你可能能够在事务中包含ALTER TABLE...SWITCH
和DBCC CHECKIDENT
(或者不包含-尚未测试过),但手动设置种子值似乎更容易和更安全。DBCC CHECKIDENT
就可以了。DBCC CHECKIDENT('<newTableName>')
。请参阅 https://msdn.microsoft.com/en-us/library/ms176057.aspx 获取更多信息。 - Eric Wu你不能将一个列更改为 IDENTITY 列。你需要做的是创建一个新的列,并从一开始就定义为 IDENTITY,然后删除旧的列,将新的列重命名为旧名称。
ALTER TABLE (yourTable) ADD NewColumn INT IDENTITY(1,1)
ALTER TABLE (yourTable) DROP COLUMN OldColumnName
EXEC sp_rename 'yourTable.NewColumn', 'OldColumnName', 'COLUMN'
马克
CREATE SEQUENCE sequence_name START WITH here_higher_number_than_max_existed_value_in_column INCREMENT BY 1;
ALTER TABLE table_name ADD CONSTRAINT constraint_name DEFAULT NEXT VALUE FOR sequence_name FOR column_name
这里有一个很不错的解决方案: SQL SERVER – Add or Remove Identity Property on Column
简而言之,在SQL Manager中手动编辑您的表,切换标识,不要保存更改,只需显示将创建用于更改的脚本,复制并稍后使用它。
这是一个巨大的时间节省器,因为(脚本)包含所有外键、索引等与更改表相关的内容。手动编写这些...天佑我们。
简单说明
使用 sp_RENAME 重命名现有列
EXEC sp_RENAME 'Table_Name.Existing_ColumnName' , 'New_ColumnName', 'COLUMN'
重命名示例:
将现有列 UserID 重命名为 OldUserID
EXEC sp_RENAME 'AdminUsers.UserID' , 'OldUserID', 'COLUMN'
然后使用alter查询添加一个新列,将其设置为主键和自增值
ALTER TABLE TableName ADD Old_ColumnName INT NOT NULL PRIMARY KEY IDENTITY(1,1)
设置主键的示例
新创建的列名为UserID。
ALTER TABLE Users ADD UserID INT NOT NULL PRIMARY KEY IDENTITY(1,1)
然后删除已重命名的列
ALTER TABLE Table_Name DROP COLUMN Renamed_ColumnName
删除重命名列的示例
ALTER TABLE Users DROP COLUMN OldUserID
我们现在在表中的现有列上添加了主键和标识。
exec sp_help 'dbo.table_name_old';
2.) 创建一个完全相同的新表,但在原有主键字段上添加一个自增字段。
3.) 禁用自增字段以移动数据。
SET IDENTITY_INSERT dbo.table_name ON
4.) 传输数据。
INSERT INTO dbo.table_name_new
(
field1, field2, etc...
)
SELECT
field1, field2, etc...
FROM
dbo.table_name_old;
5.) 确认数据已存在。
SELECT * FROM dbo.table_name_new
6.) 重新启用身份验证。
SET IDENTITY_INSERT ToyRecP.ToyAwards.lkpFile_New OFF
7.) 我发现这是获取所有外键关系的最佳脚本,以便验证原始表作为依赖项引用哪些表。 我发现了许多脚本,但这个是一个不错的选择!
SELECT f.name AS ForeignKey,
OBJECT_NAME(f.parent_object_id) AS TableName,
COL_NAME(fc.parent_object_id, fc.parent_column_id) AS ColumnName,
OBJECT_NAME (f.referenced_object_id) AS ReferenceTableName,
COL_NAME(fc.referenced_object_id, fc.referenced_column_id) AS ReferenceColumnName
FROM sys.foreign_keys AS f
INNER JOIN sys.foreign_key_columns AS fc
ON f.OBJECT_ID = fc.constraint_object_id
ORDER BY ReferenceTableName;
8.) 在进行下一步之前,请确保您拥有所有涉及表的PK和FK脚本。
9.) 您可以使用SQL Server 2008右键单击每个键并编写脚本。
10.) 使用以下语法从依赖表中删除FK:
ALTER TABLE [dbo].[table_name] DROP CONSTRAINT [Name_of_FK]
11.) 删除原始表:
DROP TABLE dbo.table_name_old;
13.) 下一步的操作需要你在第9步中创建的SQL Server 2008中的脚本。
--向新表添加PK(主键)。
--向新表添加FK(外键)。
--将FK重新添加到依赖表中。
14.) 确认所有内容都正确无误。 我使用GUI查看了表格。
15.) 将新表重命名为原始表格名称。
exec sp_RENAME '[Schema_Name.OldTableName]' , '[NewTableName]';
不能那样做,需要添加另一列,删除原始列并重命名新列或创建一个新表,复制数据并删除旧表,然后将新表重命名为旧表。
如果在SSMS中使用设计器将标识属性设置为ON,这是SQL Server在幕后执行的操作。因此,如果您有一个名为[user]的表,并将UserID设为标识,则会发生以下情况。
BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
GO
CREATE TABLE dbo.Tmp_User
(
UserID int NOT NULL IDENTITY (1, 1),
LastName varchar(50) NOT NULL,
FirstName varchar(50) NOT NULL,
MiddleInitial char(1) NULL
) ON [PRIMARY]
GO
SET IDENTITY_INSERT dbo.Tmp_User ON
GO
IF EXISTS(SELECT * FROM dbo.[User])
EXEC('INSERT INTO dbo.Tmp_User (UserID, LastName, FirstName, MiddleInitial)
SELECT UserID, LastName, FirstName, MiddleInitialFROM dbo.[User] TABLOCKX')
GO
SET IDENTITY_INSERT dbo.Tmp_User OFF
GO
GO
DROP TABLE dbo.[User]
GO
EXECUTE sp_rename N'dbo.Tmp_User', N'User', 'OBJECT'
GO
ALTER TABLE dbo.[User] ADD CONSTRAINT
PK_User PRIMARY KEY CLUSTERED
(
UserID
) ON [PRIMARY]
GO
COMMIT
话虽如此,有一种方法可以通过设置位值来黑掉系统表来实现,但这是不受支持的,我不会这样做。
IDENTITY(1, 1)
部分。 - goamn