Tsql 将任何标识列重置为以1开头作为下一个值

Tsql 将任何标识列重置为以1开头作为下一个值,tsql,sql-server-2008-r2,identity,Tsql,Sql Server 2008 R2,Identity,我正在构建一个SQL脚本来重置数据库。为此,我想清空几个(不是全部)表,并将它们的标识值重置为0 对于某些表,我使用TRUNCATE TABLE,但当表已被外键约束引用时,这不起作用。对于这些表,我使用了dbcccheckident(TableName,RESEED,0)。这适用于大多数表,但不适用于所有表。如果表从未包含任何数据,则当前标识值为NULL,而不是0: CREATE TABLE TableName (Id int identity, Value varchar(10)) DBCC

我正在构建一个SQL脚本来重置数据库。为此,我想清空几个(不是全部)表,并将它们的标识值重置为0

对于某些表,我使用
TRUNCATE TABLE
,但当表已被外键约束引用时,这不起作用。对于这些表,我使用了
dbcccheckident(TableName,RESEED,0)
。这适用于大多数表,但不适用于所有表。如果表从未包含任何数据,则当前标识值为NULL,而不是0:

CREATE TABLE TableName (Id int identity, Value varchar(10))
DBCC CHECKIDENT(TableName)

-- Checking identity information: current identity value 'NULL', current column value 'NULL'.
如果我对它们使用
dbcccheckident(TableName,RESEED,0)
,它们将有0作为下一个标识值。我可以改为使用1作为重新设定种子的值,但是其中包含数据的表将从2开始

是否可以在任何sys视图中找到下一个标识值?若我可以将下一个值放入变量中,我就可以使用它将下一个值设置为0或1。我试过使用
IDENT_CURRENT('TableName')
,但它表示空值为1,下一个值为0


请注意,我不想要任何问题,如“为什么您需要所有表都从1开始”或任何其他问题,这些问题都会提示我所要求的结果以外的其他结果。

如果所有表都有标识字段,请使用

exec sp_MSforeachtable @command1 = 'DBCC CHECKIDENT(''?'', RESEED, 1)'
MSforeachtable
是一个未记录但非常方便的存储过程,它对数据库中的所有表执行给定命令

   SELECT TableName = OBJECT_NAME(OBJECT_ID) ,
       ColumnName = name ,
       OriginalSeed = seed_value ,
       Step = increment_value ,
       LastValue = last_value ,
       IsNotForReplication = is_not_for_replication
FROM sys.identity_columns
要仅为具有标识列的表重新设定种子,可以使用下一个脚本。 它还利用了
spmsforeachtable
,但考虑了正确的表格

EXEC sp_MSforeachtable '
IF (SELECT COUNT(1) 
    FROM INFORMATION_SCHEMA.TABLES 
    WHERE TABLE_TYPE = ''BASE TABLE'' 
    AND ''[''+ TABLE_SCHEMA + ''].['' + TABLE_NAME + '']'' = ''?'' 
    AND OBJECTPROPERTY(OBJECT_ID(TABLE_NAME), ''TableHasIdentity'') = 1) > 0 
BEGIN
    DBCC CHECKIDENT (''?'', RESEED, 1)
END'
使用以下查询获取插入数据库表中的最后一个标识值

   SELECT TableName = OBJECT_NAME(OBJECT_ID) ,
       ColumnName = name ,
       OriginalSeed = seed_value ,
       Step = increment_value ,
       LastValue = last_value ,
       IsNotForReplication = is_not_for_replication
FROM sys.identity_columns

如果所有表都有标识字段,则使用

exec sp_MSforeachtable @command1 = 'DBCC CHECKIDENT(''?'', RESEED, 1)'
MSforeachtable
是一个未记录但非常方便的存储过程,它对数据库中的所有表执行给定命令

   SELECT TableName = OBJECT_NAME(OBJECT_ID) ,
       ColumnName = name ,
       OriginalSeed = seed_value ,
       Step = increment_value ,
       LastValue = last_value ,
       IsNotForReplication = is_not_for_replication
FROM sys.identity_columns
要仅为具有标识列的表重新设定种子,可以使用下一个脚本。 它还利用了
spmsforeachtable
,但考虑了正确的表格

EXEC sp_MSforeachtable '
IF (SELECT COUNT(1) 
    FROM INFORMATION_SCHEMA.TABLES 
    WHERE TABLE_TYPE = ''BASE TABLE'' 
    AND ''[''+ TABLE_SCHEMA + ''].['' + TABLE_NAME + '']'' = ''?'' 
    AND OBJECTPROPERTY(OBJECT_ID(TABLE_NAME), ''TableHasIdentity'') = 1) > 0 
BEGIN
    DBCC CHECKIDENT (''?'', RESEED, 1)
END'
使用以下查询获取插入数据库表中的最后一个标识值

   SELECT TableName = OBJECT_NAME(OBJECT_ID) ,
       ColumnName = name ,
       OriginalSeed = seed_value ,
       Step = increment_value ,
       LastValue = last_value ,
       IsNotForReplication = is_not_for_replication
FROM sys.identity_columns

为了澄清,您是否希望以后的插入都从
1开始


我不是这方面的MS-SQL专家,但是你能不能截断表,然后按照你的建议重置标识,然后如果标识为空,插入一条记录(应该得到
0
),然后删除它?这会不会让下一个要创建的记录成为
1

为了澄清,您基本上希望以后的所有插入都从
1
开始


我不是这方面的MS-SQL专家,但是你能不能截断表,然后按照你的建议重置标识,然后如果标识为空,插入一条记录(应该得到
0
),然后删除它?是否会将要创建的下一条记录保留为
1

首先禁用约束:

ALTER TABLE foo NOCHECK CONSTRAINT CK_foo_column 


然后对表执行截断操作

首先禁用约束:

ALTER TABLE foo NOCHECK CONSTRAINT CK_foo_column 


然后对表执行截断

truncate对外键约束引用的表不起作用。但是,是的,我希望以后的所有插入都从1开始。在这种情况下,它不应该让您截断-如果这些外键列中有值,您将破坏完整性,这就是约束的全部要点。我知道。我没有质疑为什么会这样。插入一条记录然后删除是一种解决方案,但如果我想对任何表执行此操作,我认为只删除表并重新创建它更容易。Truncate不适用于外键约束引用的表。但是,是的,我希望以后所有的插入都从1开始。在这种情况下,它不应该让你截断-如果你在那些外键列中有值,你会破坏完整性,这就是约束的全部要点。我知道。我没有质疑为什么会这样。插入一条记录然后删除是一种解决方案,但如果我想对任何表执行此操作,我认为只需删除该表并重新创建它就更容易了。OBJECTPROPERTY(OBJECT_ID(table_NAME),'TableHasIdentity')不会给我当前的标识值。它只告诉表是否有标识。@帕尔皮,如果表有标识字段,上述查询将下一个标识值设置为1。这是在数据库中所有表的递归中完成的。如果您有其他要求,请告诉我。当前标识值为NULL时,IDENT_CURRENT()的结果为1。当当前标识值为空时,DBCC CHECKIDENT('table',RESEED,0)的行为不同。@帕尔皮,我希望答案中的最后一个查询能够完成您的工作。似乎正是我要找的。谢谢OBJECTPROPERTY(OBJECT_ID(TABLE_名称),'TableHasIdentity')没有给我当前的标识值。它只告诉表是否有标识。@帕尔皮,如果表有标识字段,上述查询将下一个标识值设置为1。这是在数据库中所有表的递归中完成的。如果您有其他要求,请告诉我。当前标识值为NULL时,IDENT_CURRENT()的结果为1。当当前标识值为空时,DBCC CHECKIDENT('table',RESEED,0)的行为不同。@帕尔皮,我希望答案中的最后一个查询能够完成您的工作。似乎正是我要找的。谢谢