레코드를 SQL Server 데이터베이스 테이블에 삽입했습니다. 테이블에 기본 키가 정의되어 있고 자동 증가 ID 시드가 "예"로 설정되어 있습니다. 이는 주로 SQL Azure에서 각 테이블에 기본 키와 ID가 정의되어 있어야하기 때문에 수행됩니다.
그러나 테이블에서 일부 레코드를 삭제해야하기 때문에 해당 테이블의 ID 시드가 방해 받고 인덱스 열 (1 씩 증가하여 자동 생성됨)이 방해 받게됩니다.
열을 숫자 순서로 오름차순으로 정렬하도록 레코드를 삭제 한 후 ID 열을 어떻게 다시 설정할 수 있습니까?
식별 C 럼은 데이터베이스의 외부 키로 사용되지 않습니다.
DBCC CHECKIDENT
관리 명령은 ID 카운터를 재설정하는 데 사용됩니다. 명령 구문은 다음과 같습니다.
_DBCC CHECKIDENT (table_name [, { NORESEED | { RESEED [, new_reseed_value ]}}])
[ WITH NO_INFOMSGS ]
_
예:
_DBCC CHECKIDENT ('[TestTable]', RESEED, 0);
GO
_
이전 버전의 Azure SQL Database에서는 지원되지 않았지만 지금 지원됩니다.
_new_reseed_value
_ 인수는 SQL Server 버전에 따라 다릅니다. 설명서에 따라 :
테이블에 행이 있으면 다음 행이 new_reseed_value 값과 함께 삽입됩니다. SQL Server 2008 R2 이전 버전에서 삽입 된 다음 행은 new_reseed_value + 현재 증분 값을 사용합니다.
그러나 관찰 된 동작은 적어도 SQL Server 2012가 여전히 new_reseed_value + 현재 증분을 사용하고 있음을 나타 내기 때문에 이 정보가 잘못된 것입니다 (실제로는 잘못 잘못됨) 가치 논리. 마이크로 소프트는 같은 페이지에있는 _Example C
_ 자체와도 모순된다 :
C. 현재 아이덴티티 값을 새로운 값으로 강제
다음 예제에서는 AddressType 테이블의 AddressTypeID 열에있는 현재 ID 값을 10으로 설정합니다. 테이블에 기존 행이 있으므로 삽입 된 다음 행은 11을 값, 즉 새 현재 증분 값으로 사용합니다. 열 값에 1을 더한 값입니다.
_USE AdventureWorks2012;
GO
DBCC CHECKIDENT ('Person.AddressType', RESEED, 10);
GO
_
그럼에도 불구하고 이것은 모두 최신 SQL Server 버전에서 다른 동작에 대한 옵션을 남깁니다. Microsoft가 자체 문서에서 내용을 정리할 때까지 사용하기 전에 실제 테스트를 수행하는 것이 유일한 방법이라고 생각합니다.
DBCC CHECKIDENT ('TestTable', RESEED, 0)
GO
여기서 0은 identity
시작 값
데이터의 IF all 가 DELETE
(즉, WHERE
절이 없음)을 통해 테이블에서 제거되는 경우 a) 권한이 허용하는 한 b) FK가 없음을 유의해야합니다 TRUNCATE TABLE
를 사용하여 테이블을 참조하는 것이 선호 될 것입니다. 왜냐하면 더 효율적인 DELETE
및 은 IDENTITY
시드를 동시에 재설정하기 때문입니다. 다음 세부 정보는 TRUNCATE TABLE 에 대한 MSDN 페이지에서 가져온 것입니다.
TRUNCATE TABLE에는 DELETE 문과 비교할 때 다음과 같은 이점이 있습니다.
더 적은 트랜잭션 로그 공간이 사용됩니다.
DELETE 문은 한 번에 하나씩 행을 제거하고 삭제 된 각 행에 대한 트랜잭션 로그에 항목을 기록합니다. TRUNCATE TABLE은 테이블 데이터를 저장하는 데 사용 된 데이터 페이지를 할당 해제하여 데이터를 제거하고 페이지 할당 취소 만 트랜잭션 로그에 기록합니다.
자주 사용되는 잠금이 적습니다.
행 잠금을 사용하여 DELETE 문을 실행하면 테이블의 각 행이 잠겨 삭제됩니다. TRUNCATE TABLE은 항상 테이블 (SCH-M 잠금 포함)과 각 행이 아닌 페이지를 잠급니다.
예외없이 테이블에 제로 페이지가 남아 있습니다.
DELETE 문이 실행 된 후에도 테이블에는 여전히 빈 페이지가 포함될 수 있습니다. 예를 들어, 힙의 빈 페이지는 배타적 (LCK_M_X) 테이블 잠금이 없으면 할당을 해제 할 수 없습니다. 삭제 작업에서 테이블 잠금을 사용하지 않으면 테이블 (힙)에 빈 페이지가 많이 포함됩니다. 인덱스의 경우, 삭제 작업은 빈 페이지를 뒤에 남겨 둘 수 있지만, 이러한 페이지는 백그라운드 정리 프로세스에 의해 신속하게 할당 취소됩니다.
테이블에 ID 열이 있으면 해당 열의 카운터가 열에 대해 정의 된 시드 값으로 다시 설정됩니다. 시드가 정의되지 않은 경우 기본값 1이 사용됩니다. ID 카운터를 유지하려면 대신 DELETE를 사용하십시오.
그래서 다음과 같습니다 :
DELETE FROM [MyTable];
DBCC CHECKIDENT ('[MyTable]', RESEED, 0);
된다.
TRUNCATE TABLE [MyTable];
제약 등에 관한 추가 정보는 위의 링크 된 TRUNCATE TABLE
문서를 참조하십시오.
대부분의 답변은 RESEED를 0으로 제안하지만, 다음 번 ID를 다시 사 용할 때가 많습니다.
declare @max int
select @max=max([Id])from [TestTable]
if @max IS NULL //check when max is returned as null
SET @max = 0
DBCC CHECKIDENT ('[TestTable]', RESEED,@max)
그러면 테이블이 점검되고 다음 ID로 재설정됩니다.
나는 @anil shahs
대답을 시도하고 신원을 다시 설정합니다. 그러나 새로운 행이 삽입되면 identity = 2
를 얻습니다. 대신 구문을 다음과 같이 변경했습니다.
DELETE FROM [TestTable]
DBCC CHECKIDENT ('[TestTable]', RESEED, 0)
GO
그런 다음 첫 번째 행에 ID = 1이 생깁니다.
대부분의 답변은 RESEED
을 0
로 제안하지만 일부는이를 TRUNCATED
테이블의 결함으로 보는 반면 Microsoft는 ID
을 제외하는 솔루션을 제공합니다
DBCC CHECKIDENT ('[TestTable]', RESEED)
이렇게하면 테이블을 확인하고 다음 ID
로 재설정됩니다. 이것은 현재까지 MS SQL 2005부터 사용 가능합니다.
@jacob
DBCC CHECKIDENT ('[TestTable]', RESEED,0)
DBCC CHECKIDENT ('[TestTable]', RESEED)
나를 위해 일한, 난 그냥 테이블에서 모든 항목을 먼저 지우고 삭제 후 트리거 지점에서 위의 추가했다. 지금은 항목을 삭제할 때마다 거기에서 가져옵니다.
새로운 ID로 ID 열 재설정 ...
DECLARE @MAX INT
SELECT @MAX=ISNULL(MAX(Id),0) FROM [TestTable]
DBCC CHECKIDENT ('[TestTable]', RESEED,@MAX)
발급 2 명령 트릭을 할 수있는
DBCC CHECKIDENT ('[TestTable]', RESEED,0)
DBCC CHECKIDENT ('[TestTable]', RESEED)
첫 번째는 ID를 0으로 재설정하고, 다음은 사용 가능한 다음 값으로 설정합니다. - jacob
이것은 일반적인 질문이며 답변은 항상 동일합니다.하지 마십시오. 신원 값은 임의적으로 취급되어야하며, 따라서 "올바른"주문이 없습니다.
Truncate
테이블은 레코드를 지우고 카운터를 재설정하고 dis 공간을 회수하기 때문에 선호됩니다.
Delete
및 CheckIdent
은 외부 키가자를 수없는 경우에만 사용해야합니다.
이 스크립트를 실행하여 ID 열을 재설정하십시오. 두 가지를 변경해야합니다. tableXYZ를 업데이트해야하는 테이블로 바꾸십시오. 또한 식별 컬럼의 이름은 임시 테이블에서 제거해야합니다. 이것은 35,000 개의 행과 3 개의 열이있는 테이블에서 즉시 발생했습니다. 분명히, 테이블을 백업하고 먼저 테스트 환경에서 이것을 시도하십시오.
select *
into #temp
From tableXYZ
set identity_insert tableXYZ ON
truncate table tableXYZ
alter table #temp drop column (nameOfIdentityColumn)
set identity_insert tableXYZ OFF
insert into tableXYZ
select * from #temp
이 저장 프로 시저를 사용하십시오.
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 서버 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, Item 1
를 생성합니다. 테이블을 만든 직후에 리셋을 실행하면 다음 값은 0이됩니다. 솔직히 Microsoft는이 문제를 올바르게 처리 할 수 없다는 사실에 놀라지 않습니다. 내가 테이블을 다시 생성 한 후 가끔씩 실행되는 참조 테이블을 채우는 스크립트 파일이 있고 테이블이 이미 만들어져 있기 때문에 발견했습니다.
테이블 전체를 정리하지 않는 한 0으로 다시 시드하는 것은 실용적이지 않습니다.
다른 현명한 Anthony Raymond의 답변은 완벽합니다. 최대 식별 열을 먼저 얻은 다음 최대로 시드하십시오.
행을 완전히 삭제하고 IDENTITY 개수를 다시 설정하려면이 (SQL Server 2008 R2)
USE mydb
-- ##################################################################################################################
-- DANGEROUS!!!! USE WITH CARE
-- ##################################################################################################################
DECLARE
db_cursor CURSOR FOR
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND TABLE_CATALOG = 'mydb'
DECLARE @tblname VARCHAR(50)
SET @tblname = ''
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO @tblname
WHILE @@FETCH_STATUS = 0
BEGIN
IF CHARINDEX('mycommonwordforalltablesIwanttodothisto', @tblname) > 0
BEGIN
EXEC('DELETE FROM ' + @tblname)
DBCC CHECKIDENT (@tblname, RESEED, 0)
END
FETCH NEXT FROM db_cursor INTO @tblname
END
CLOSE db_cursor
DEALLOCATE db_cursor
GO
다음 스크립트를 사용하여이 작업을 수행합니다. 테이블에서 모든 행을 삭제하고 "IDENT_CURRENT
"가 현재 1로 설정되어있는 경우 (즉, 테이블에 행이 하나만있는 경우)와 같은 "오류"가 발생하는 시나리오는 하나뿐입니다.
DECLARE @maxID int = (SELECT MAX(ID) FROM dbo.Tbl)
;
IF @maxID IS NULL
IF (SELECT IDENT_CURRENT('dbo.Tbl')) > 1
DBCC CHECKIDENT ('dbo.Tbl', RESEED, 0)
ELSE
DBCC CHECKIDENT ('dbo.Tbl', RESEED, 1)
;
ELSE
DBCC CHECKIDENT ('dbo.Tbl', RESEED, @maxID)
;
DBCC CHECKIDENT (<TableName>, reseed, 0)
그러면 현재 ID 값이 0으로 설정됩니다.
다음 값을 삽입하면 ID 값이 1로 증가합니다.