我需要将一个表的主键更改为一个标识列,并且在表中已经有许多行。

我有一个脚本来清理id,以确保它们从1开始是顺序的,在我的测试数据库上运行良好。

更改列以具有标识属性的SQL命令是什么?


当前回答

您不能这样做,您需要添加另一列,删除原来的列并重命名新列,或者创建一个新表,复制数据并删除旧表,然后将新表重命名为旧表

如果你使用SSMS并在设计器中将标识属性设置为ON,下面就是SQL Server在幕后所做的事情。因此,如果你有一个名为[user]的表,如果你设置UserID和identity,就会发生这样的情况

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

已经说过,有一种方法可以通过设置位值来破解系统表,但这是不支持的,我不会这么做

其他回答

我是一名java开发人员,碰巧加入了一个没有DBA的团队,而作为一名开发人员,我无法获得DBA权限。我的任务是在两个数据库之间移动整个模式,所以没有DBA,我必须通过运行脚本来完成,不能使用SQL Server 2008中的GUI,因为我没有管理权限。

但是,在新模式上运行存储过程时,所有内容都被移动了。表,我发现我丢失了一个表的标识字段。我仔细检查了创建表的脚本,它在那里,但是,SQL Server在我运行脚本时没有得到它。后来,一位DBA告诉我,他以前见过同样的问题。

在任何情况下,对于SQL Server 2008,这些是我采取的步骤来解决这个问题,他们工作,所以我张贴在这里,希望它会对某人有所帮助。这是我所做的,因为我对另一个表有FK依赖,这使得这更困难:

我使用这个查询来验证标识确实缺失,并查看表上的依赖关系。

1)。查找表上的统计信息:

exec sp_help 'dbo.table_name_old';

2)。创建一个重复的、完全相同的新表,只是在原来的PK字段上添加了一个标识字段。

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)。这是我找到的获得所有FK关系以验证原始表引用哪个表作为依赖项的最佳脚本 我遇到过很多,所以它是一个保存者!

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)。接下来的步骤依赖于您在SQL Server 2008第9步中创建的脚本。

将PK添加到新表中。

——将FK添加到新表中。

——将FK添加回依赖项表。

14)。验证所有内容是否正确和完整。我使用GUI查看表格。

15)。将新表重命名为原始表名。

exec sp_RENAME '[Schema_Name.OldTableName]' , '[NewTableName]';

最后,一切都成功了!

As I understood in normal cases we are creating a table with Primary key which is having Identity property So Rename or Delete a column which is associated with Primary Key constraint will not be possible because constraint Rules are validating column structure. Tto achieve this we have to process some steps in the following way: Let us assume TableName = 'Employee' and ColumnName = 'EmployeeId' 1. Add new column 'EmployeeId_new' in the 'Employee' table ALTER TABLE Employee ADD EmployeeId_new INT IDENTITY(1,1)

Now remove column 'EmployeeId' from 'Employee' table ALTER TABLE Employee DROP COLUMN EmployeeId This will throw error because of Primary Key Constraint rules are applicable and validating column structure. *### 'Msg 5074, Level 16, State 1, Line 1 The object [PK_dbo.Employee] is dependent on colmn [EmployeeId].'### So we have to remove the Primary Key constraint first from the table 'Employee' then we can remove the column ALTER TABLE Employee DROP constraint [PK_dbo.Employee] Now we can remove the column 'EmployeeId' from 'Employee' table as did in the previous step where we got error ALTER TABLE Employee DROP COLUMN EmployeeId Now Column 'EmployeeId' removed from table So we will Rename the newly added new column 'EmployeeId_new' with 'EmployeeId' sp_rename 'Employee.EmployeeId', 'EmployeeId_new', 'COLUMN' To rearrange the table in the same form as It was, we have to add Primary Key Constraint for the column 'EmployeeId' ALTER TABLE Employee add constraint [PK_dbo.Employee] primary key (EmployeeId)

8. 现在,带有'EmployeeId'的表'Employee'随着现有的主键约束被修改为Identity规则

您不能更改现有列的标识。

你有两个选择,

创建一个带有标识的新表并删除现有表 创建一个具有标识的新列并删除现有列

方法1。(新表)在这里,您可以保留新创建的标识列上的现有数据值。请注意,如果不满足'if not exists',您将丢失所有数据,因此请确保您将条件也放在drop上!

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'

方法2(新列)不能在新创建的标识列上保留现有数据值,标识列将保留数字序列。

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'

请参阅以下Microsoft SQL Server论坛帖子了解更多细节:

如何将列更改为identity(1,1)

我不相信您可以使用tsql将现有列更改为标识列。但是,您可以通过Enterprise Manager设计视图来完成。

或者,您可以创建一个新行作为标识列,删除旧列,然后重命名新列。

ALTER TABLE FooTable
ADD BarColumn INT IDENTITY(1, 1)
               NOT NULL
               PRIMARY KEY CLUSTERED

基本上有四个逻辑步骤。

创建一个新的Identity列。为这个新列打开Insert Identity。 将源列(希望转换为Identity的列)中的数据插入到这个新列中。 关闭新列的Insert Identity。 删除源列并将新列重命名为源列的名称。

可能会有一些更复杂的事情,比如跨多个服务器工作等。

有关步骤(使用ssms和T-sql),请参阅下面的文章。这些步骤适用于不太熟悉T-SQL的初学者。

http://social.technet.microsoft.com/wiki/contents/articles/23816.how-to-convert-int-column-to-identity-in-the-ms-sql-server.aspx