在列上设置标识

时间:2011-03-03 13:27:30

标签: sql tsql sql-server-2008

如何使用T-SQL在PK列上修改表和设置标识?

感谢您的帮助

6 个答案:

答案 0 :(得分:3)

您无法修改现有列以获得IDENTITY“属性” - 您必须:

  • 创建一个具有相同结构的新表(但设置了IDENTITY),
  • 为这个新表启用IDENTITY_INSERT
  • 将旧表中的行插入新表
  • 放下旧桌子,
  • 将新表重命名为旧表名。

如果涉及外键,您还需要修复它们。

答案 1 :(得分:3)

此问题的大多数解决方案的问题是它们需要向表中添加新列或完全重建表。

两者都需要大量的锁定和日志记录活动,我一直觉得这很烦人,因为这只是元数据的改变而且根本不需要触摸数据页面(事实上,可以直接通过启动来更新元数据单用户模式下的实例,并在sys.syscolpars中弄乱了一些列但是没有记录/不支持。)

然而,this connect item上发布的变通方法显示了一种完全受支持的方式,可以使用ALTER TABLE...SWITCH(信用SQLKiwi

将其转换为仅元数据更改

示例代码。

设置没有identity列的测试表。

CREATE TABLE dbo.tblFoo 
(
bar INT PRIMARY KEY,
filler CHAR(8000),
filler2 CHAR(49)
)


INSERT INTO dbo.tblFoo (bar)
SELECT TOP (10000) ROW_NUMBER() OVER (ORDER BY (SELECT 0))
FROM master..spt_values v1, master..spt_values v2

将其改为identity列(或多或少即时)。

BEGIN TRY;
    BEGIN TRANSACTION;

    /*Using DBCC CHECKIDENT('dbo.tblFoo') is slow so use dynamic SQL to
      set the correct seed in the table definition instead*/
    DECLARE @TableScript nvarchar(max)
    SELECT @TableScript = 
    '
    CREATE TABLE dbo.Destination(
        bar INT IDENTITY(' + 
                     CAST(ISNULL(MAX(bar),0)+1 AS VARCHAR) + ',1)  PRIMARY KEY,
        filler CHAR(8000),
        filler2 CHAR(49)
        )

        ALTER TABLE dbo.tblFoo SWITCH TO dbo.Destination;
    '       
    FROM dbo.tblFoo
    WITH (TABLOCKX,HOLDLOCK)

    EXEC(@TableScript)


    DROP TABLE dbo.tblFoo;

    EXECUTE sp_rename N'dbo.Destination', N'tblFoo', 'OBJECT';


    COMMIT TRANSACTION;
END TRY
BEGIN CATCH
    IF XACT_STATE() <> 0 ROLLBACK TRANSACTION;
    PRINT ERROR_MESSAGE();
END CATCH;

测试结果。

INSERT INTO dbo.tblFoo (filler,filler2) 
OUTPUT inserted.*
VALUES ('foo','bar')

给出

bar         filler    filler2
----------- --------- ---------
10001       foo       bar      

清理

DROP TABLE dbo.tblFoo

答案 2 :(得分:0)

实际上,您可以修改列上的IDENTITY。 请仔细阅读本文http://www.sqlmag.com/article/tsql3/adding-the-identity-property-to-an-existing-column.aspx

虽然

,但需要比ALTER TABLE tab ALTER COLUMN col SET IDENTITY更多的代码

答案 3 :(得分:0)

您需要使用ALTER TABLE命令 - 始终先在开发或预生产中测试!

示例G似乎最接近您的要求:

CREATE TABLE dbo.doc_exe(column_a INT CONSTRAINT column_a_un UNIQUE); 走 ALTER TABLE dbo.doc_exe ADD

- 添加PRIMARY KEY标识列。 column_b INT IDENTITY CONSTRAINT column_b_pk PRIMARY KEY,

请参阅http://msdn.microsoft.com/en-us/library/ms190273.aspx

答案 4 :(得分:0)

由于您只能忽略insert的身份列,而不能忽略update的身份列,因此您需要一个中间表。这是一个例子:

create table TestTable (pk int constraint PK_TestTable primary key, 
    name varchar(30))
create table TestTable2 (pk int constraint PK_TestTable identity primary key, 
    name varchar(30))
set identity_insert TestTable2 on
insert TestTable2 (pk, name) select pk, name from TestTable
set identity_insert TestTable2 off
drop table TestTable
exec sp_rename 'TestTable2', 'TestTable'

答案 5 :(得分:0)

这是你正在寻找的答案吗?

DBCC CHECKIDENT( 
    'DBName.dbo.TableName'
    ,RESEED --[, new_reseed_value ]
)

使用示例:

DBCC CHECKIDENT( 
    'DBName.dbo.TableName'
)

检查身份信息:当前身份值&#39; 1&#39;,当前列值&#39; 1211031236&#39; DBCC执行完成。如果DBCC打印了错误消息,请与系统管理员联系。

DBCC CHECKIDENT( 
    'DBName.dbo.TableName'
    ,RESEED --[, new_reseed_value ]
)

检查身份信息:当前身份值&#39; 1211031236&#39;,当前列值&#39; 1211031236&#39;。 DBCC执行完成。如果DBCC打印了错误消息,请与系统管理员联系。