我已经将记录插入到SQL Server数据库表中。该表定义了一个主键,并且自动递增标识种子被设置为“Yes”。这样做主要是因为在SQL Azure中,每个表都必须定义一个主键和标识。
但是由于我必须从表中删除一些记录,这些表的标识种子将受到干扰,索引列(自动生成的增量为1)也将受到干扰。
如何在删除记录后重置标识列,使该列具有升序数字顺序?
标识列在数据库中的任何地方都不能用作外键。
我已经将记录插入到SQL Server数据库表中。该表定义了一个主键,并且自动递增标识种子被设置为“Yes”。这样做主要是因为在SQL Azure中,每个表都必须定义一个主键和标识。
但是由于我必须从表中删除一些记录,这些表的标识种子将受到干扰,索引列(自动生成的增量为1)也将受到干扰。
如何在删除记录后重置标识列,使该列具有升序数字顺序?
标识列在数据库中的任何地方都不能用作外键。
当前回答
第一个:标识规范只是:“No”>>保存数据库执行项目
之后:身份规范只是:“是”>>保存数据库执行项目
您的数据库ID, PK从1 >>开始
其他回答
DBCC CHECKIDENT management命令用于重置标识计数器。命令格式为:
DBCC CHECKIDENT (table_name [, { NORESEED | { RESEED [, new_reseed_value ]}}])
[ WITH NO_INFOMSGS ]
例子:
DBCC CHECKIDENT ('[TestTable]', RESEED, 0);
GO
以前版本的Azure SQL数据库不支持,但现在支持了。
多亏了Solomon Rutzky,该命令的文档现在已经修复。
使用这个存储过程:
IF (object_id('[dbo].[pResetIdentityField]') IS NULL)
BEGIN
EXEC('CREATE PROCEDURE [dbo].[pResetIdentityField] AS SELECT 1 FROM DUMMY');
END
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[pResetIdentityField]
@pSchemaName NVARCHAR(1000)
, @pTableName NVARCHAR(1000) AS
DECLARE @max INT;
DECLARE @fullTableName NVARCHAR(2000) = @pSchemaName + '.' + @pTableName;
DECLARE @identityColumn NVARCHAR(1000);
SELECT @identityColumn = c.[name]
FROM sys.tables t
INNER JOIN sys.schemas s ON t.[schema_id] = s.[schema_id]
INNER JOIN sys.columns c ON c.[object_id] = t.[object_id]
WHERE c.is_identity = 1
AND t.name = @pTableName
AND s.[name] = @pSchemaName
IF @identityColumn IS NULL
BEGIN
RAISERROR(
'One of the following is true: 1. the table you specified doesn''t have an identity field, 2. you specified an invalid schema, 3. you specified an invalid table'
, 16
, 1);
RETURN;
END;
DECLARE @sqlString NVARCHAR(MAX) = N'SELECT @maxOut = max(' + @identityColumn + ') FROM ' + @fullTableName;
EXECUTE sp_executesql @stmt = @sqlString, @params = N'@maxOut int OUTPUT', @maxOut = @max OUTPUT
IF @max IS NULL
SET @max = 0
print(@max)
DBCC CHECKIDENT (@fullTableName, RESEED, @max)
go
--exec pResetIdentityField 'dbo', 'Table'
回顾一下我的答案。我在sql server 2008 r2中遇到了一个奇怪的行为,你应该知道。
drop table test01
create table test01 (Id int identity(1,1), descr nvarchar(10))
execute pResetIdentityField 'dbo', 'test01'
insert into test01 (descr) values('Item 1')
select * from test01
delete from test01
execute pResetIdentityField 'dbo', 'test01'
insert into test01 (descr) values('Item 1')
select * from test01
第一个选择生成0,Item 1。
第二个生成1,项目1。如果在表创建后立即执行重置,则下一个值为0。老实说,我并不惊讶微软不能把这些东西做好。我发现它是因为我有一个填充引用表的脚本文件,有时在重新创建表后运行,有时在已经创建表时运行。
DBCC CHECKIDENT (<TableName>, reseed, 0)
这将把当前标识值设置为0。
在插入下一个值时,标识值将增加到1。
你可以CHECKIDENT重置种子
DBCC CHECKIDENT
(
table_name
[ , { NORESEED | { RESEED [ , new_reseed_value ] } } ]
)
[ WITH NO_INFOMSGS ]
例子
DBCC CHECKIDENT ('TAble', reseed,0)
-- 示例查询
您可以用以下代码插入基本数据
向表中插入数据后,先创建一个表
步骤到步骤i显示数据和删除数据显示细节理解代码
结果代码:创建带有rest种子Id的表 我用的是车管局系统。Identity_columns表具有标识
--Create Table
DROP TABLE IF EXISTS ExampleTable
create table ExampleTable (Id Bigint identity(1,1), Name nvarchar(10))
--Insert to ExampleTable and Delete and Show identity
insert into ExampleTable (Name)
select 'Test1' as NAme union all select 'Test2' as NAme
select * from ExampleTable
| Id | Name |
| -------- | -----|
| 1 |Test1 |
| 2 |Test2 |
delete from ExampleTable
insert into ExampleTable (Name) select 'Test3' as NAme
select * from ExampleTable
| Id | Name |
| -------- | -----|
| 3 |Test3 |
delete from ExampleTable
首次检查数据 如果表中没有数据使用种子表
如果表中有数据,使用最大id
之后用CHECKIDENT改变种子
--Find seedTable
declare @reseed int=0
if(not exists( select top 1 * from ExampleTable))
begin
SELECT
@reseed=cast( seed_value as int)
FROM sys.tables tables
JOIN sys.identity_columns identity_columns
ON tables.object_id=identity_columns.object_id
where
tables.name='ExampleTable'
and OBJECT_SCHEMA_NAME(tables.object_id, db_id())='dbo'
set @reseed=@reseed -1
end
else
begin
--if Table Has Data and use Max id For seed
set @reseed=(select top 1 id from ExampleTable order by id desc)
end
DBCC CHECKIDENT ('ExampleTable', reseed,@reseed)
insert into ExampleTable
(Name)
select 'Test4' as NAme
select * from ExampleTable
| Id | Name |
| -------- | -----|
| 1 |Test4 |
GO
对所有表使用这个sp:
补播“youtable”
在删除一条记录后(在触发程序中)
ALTER PROCEDURE [dbo].[RESEED](@Tabla nvarchar(100))
as
-- ********************* CREAR ESTA FUNCIÓN PRIMERO *******************************
/*
create function dbo.FN_EsIdentidad(@Tabla nvarchar(100), @Campo nvarchar(100))
returns int
as
begin
return columnproperty ( object_id ( @Tabla ), @Campo , 'IsIdentity')
end
GO
************************************************************************************
*/
declare @CampoIdentidad nvarchar(100)
SELECT @CampoIdentidad = Column_Name
--,dbo.FN_EsIdentidad(Table_Name, Column_name) as EsIdentidad,
--table_name, column_name
FROM information_schema.columns
where dbo.FN_EsIdentidad(Table_Name, Column_name) = 1
and Table_Name=@Tabla
declare @Sql nvarchar(max)
declare @OutPutNum int
set @Sql = 'Select MAX(' + @CampoIdentidad + ') From ' + @Tabla
--select @CampoIdentidad
set @sql = 'Select @ValorOut=max(' + @CampoIdentidad + ') From ' + @Tabla
declare @ParamDefinition nvarchar(max)
SET @ParamDefinition = '@ValorOut int OUTPUT'
EXECUTE sp_executesql
@SQL
,@ParamDefinition
,@ValorOut = @OutPutNum OUTPUT;
--select @OutPutNum
set @OutPutNum = coalesce(@OutPutNum ,0)
DBCC CHECKIDENT (@Tabla, RESEED, @OutputNum)