我有SQL Server数据库,我想改变标识列,因为它开始了 有一个大数字10010,它与另一个表相关,现在我有200条记录,我想在记录增加之前修复这个问题。

更改或重置该列的最佳方法是什么?


当前回答

如果您特别需要将主键值更改为不同的数字(例如123 -> 1123)。identity属性阻止更改PK值。Set Identity_insert将不起作用。如果您有级联删除,则不建议执行插入/删除操作(除非您关闭了引用完整性检查)。

编辑:新版本的SQL不允许更改syscolumns实体,因此我的部分解决方案必须以艰难的方式完成。关于如何从主键中删除Identity,请参考这个SO: 从表中的列中删除Identity 这个脚本将在PK中关闭标识:

***********************

sp_configure 'allow update', 1
go
reconfigure with override
go


update syscolumns set colstat = 0 --turn off bit 1 which indicates identity column
where id = object_id('table_name') and name = 'column_name'
go


exec sp_configure 'allow update', 0
go
reconfigure with override
go

***********************

接下来,您可以设置关系,以便它们更新外键引用。否则你需要关闭关系强制执行。这个SO链接展示了如何: 如何使用T-SQL临时禁用外键约束?

现在,您可以进行更新。我写了一个简短的脚本来基于相同的列名编写所有的更新SQL(在我的情况下,我需要将CaseID增加1,000,000:

select 
'update ['+c.table_name+'] SET ['+Column_Name+']=['+Column_Name+']+1000000'
from Information_Schema.Columns as c
JOIN Information_Schema.Tables as t ON t.table_Name=c.table_name and t.Table_Schema=c.table_schema and t.table_type='BASE TABLE'
where Column_Name like 'CaseID' order by Ordinal_position

最后,重新启用引用完整性,然后重新启用主键上的Identity列。

注意:我看到有些人在这些问题上问为什么。在我的例子中,我必须将来自第二个生产实例的数据合并到主DB中,这样才能关闭第二个实例。我只需要所有操作数据的PK/ fk不发生冲突。元数据fk是相同的。

其他回答

这发生在我身上,因为我做了一个合并,它更新了我正在进行合并的ID。

失败的例子(注意ClownID):

    MERGE ArchitectMain.dbo.BackendClowns AS TGT 
   USING (
    SELECT ClownID
        ,ClownName
        ,Description
        ,Active
        ,EmailSubject
        ,AddedBy
        ,Added
    FROM #temptable1
    ) AS SRC(ClownID, ClownName, Description, Active, EmailSubject, AddedBy, Added)
    ON (TGT.ClownID = SRC.ClownID)
WHEN MATCHED
    THEN
        UPDATE
        SET ClownID = SRC.ClownID
            ,ClownName = SRC.ClownName
            ,Description = SRC.Description
            ,Active = SRC.Active
            ,EmailSubject = SRC.EmailSubject
            ,AddedBy = SRC.AddedBy
            ,Added = SRC.Added;

示例(注意ClownID):

MERGE ArchitectMain.dbo.BackendClowns AS TGT
USING (
    SELECT ClownID
        ,ClownName
        ,Description
        ,Active
        ,EmailSubject
        ,AddedBy
        ,Added
    FROM #temptable1
    ) AS SRC(ClownID, ClownName, Description, Active, EmailSubject, AddedBy, Added)
    ON (TGT.ClownID = SRC.ClownID)
WHEN MATCHED
    THEN
        UPDATE
        SET ClownName = SRC.ClownName
            ,Description = SRC.Description
            ,Active = SRC.Active
            ,EmailSubject = SRC.EmailSubject
            ,AddedBy = SRC.AddedBy
            ,Added = SRC.Added;
            

如果你的问题答对了,你想做的是

update table
set identity_column_name = some value

让我告诉你,这不是一个简单的过程,使用它是不可取的,因为它可能有一些相关的外键。

但这里有一些步骤,请采取备份表

步骤1-选择表的设计视图

步骤2-关闭标识列

现在可以使用更新查询了。

现在重做第1步和第2步,并打开标识列

参考

就我所见,有几种方法可以做到这一点。,但在我看来最好和最快的方法是以下一种:

标识列有一个计数器,它不一定与已注册的列相同,您可以使用以下SQL命令查看该计数器的值:

DBCC CHECKIDENT('tableName', NORESEED);

然后,如果你想编辑标识列,你将不能,但我建议在重新播种计数器到你需要的数字后,做一个新的寄存器。要重新播种计数器,使用以下命令:

DBCC CHECKIDENT('tableName', RESEED, desiredNumber);

如果您特别需要将主键值更改为不同的数字(例如123 -> 1123)。identity属性阻止更改PK值。Set Identity_insert将不起作用。如果您有级联删除,则不建议执行插入/删除操作(除非您关闭了引用完整性检查)。

编辑:新版本的SQL不允许更改syscolumns实体,因此我的部分解决方案必须以艰难的方式完成。关于如何从主键中删除Identity,请参考这个SO: 从表中的列中删除Identity 这个脚本将在PK中关闭标识:

***********************

sp_configure 'allow update', 1
go
reconfigure with override
go


update syscolumns set colstat = 0 --turn off bit 1 which indicates identity column
where id = object_id('table_name') and name = 'column_name'
go


exec sp_configure 'allow update', 0
go
reconfigure with override
go

***********************

接下来,您可以设置关系,以便它们更新外键引用。否则你需要关闭关系强制执行。这个SO链接展示了如何: 如何使用T-SQL临时禁用外键约束?

现在,您可以进行更新。我写了一个简短的脚本来基于相同的列名编写所有的更新SQL(在我的情况下,我需要将CaseID增加1,000,000:

select 
'update ['+c.table_name+'] SET ['+Column_Name+']=['+Column_Name+']+1000000'
from Information_Schema.Columns as c
JOIN Information_Schema.Tables as t ON t.table_Name=c.table_name and t.Table_Schema=c.table_schema and t.table_type='BASE TABLE'
where Column_Name like 'CaseID' order by Ordinal_position

最后,重新启用引用完整性,然后重新启用主键上的Identity列。

注意:我看到有些人在这些问题上问为什么。在我的例子中,我必须将来自第二个生产实例的数据合并到主DB中,这样才能关闭第二个实例。我只需要所有操作数据的PK/ fk不发生冲突。元数据fk是相同的。

尝试使用DBCC CHECKIDENT:

DBCC CHECKIDENT ('YourTable', RESEED, 1);