삭제 후 SQL Server에서 자동 증분 재설정


265

SQL Server 데이터베이스의 테이블에서 일부 레코드를 삭제했습니다. 이제 ID가 101에서 1200으로 변경되었습니다. 레코드를 다시 삭제하고 싶지만 ID가 다시 102로 돌아 가기를 원합니다. SQL Server에서이를 수행 할 수있는 방법이 있습니까?


46
"하지 마십시오"라고 말하지 마십시오. 내가 무언가를하는 방법을 물어볼 때 나는 그것을 싫어하고 내가 얻는 전부는 그렇지 않다. 예, ID를 재설정하면 외래 키 문제가 발생할 수 있지만 데이터베이스와 프로그램을 알지 못하는 경우에만 가능합니다. sceduled delete 후 ID를 재설정하는 데는 매우 좋은 이유가 있습니다.이를 Auditors라고합니다. 감사인은 차이를보고 싶어서이를 채우고 통제 된 방식으로 수행하며 외래 키 제약 조건을 유지해야합니다.

6
@ spyder, 레코드 삽입을 삭제하기 위해 롤백하지 않으면 공백이 있음을 알고 있습니까? 자동 증가와의 차이를 피할 수 없으며 시도하는 것이 어리 석습니다. 감사 기관에서 근무했으며 유능한 감사관이이를 설명 할 수 있습니다. 또한 적절한 감사 테이블이 있으면 해당 레코드에서 발생한 상황을 볼 수 있습니다. 또는 법적인 이유로 간격이 없어야하는 경우 (이 경우에는 몇 가지 경우가 있음) 무능한 개발자 만 자동 증분을 사용하여 감사자가 올바르게 화를 내게됩니다.
HLGEM

답변:


454

다음 명령을 실행하여 mytable을 다시 시작하여 1부터 시작하십시오.

DBCC CHECKIDENT (mytable, RESEED, 0)

온라인 설명서 (BOL, SQL 도움말)에서 이에 대해 읽으십시오. 또한 설정하려는 시드보다 높은 레코드가 없는지주의하십시오.


4
...이 레코드의 ID는 다시 행복하게 재사용되어 나쁜 혼란을 초래하기 때문입니다.
nalply

3
실제로 1에서 ID를 시작하려면 0을 사용해야합니다. DBCC CHECKIDENT (mytable, RESEED, 0)
Ryan Lundy

7
"DBCC CHECKIDENT (table_name)"은 "조심할 필요"보다 시드를 테이블에서 가장 높은 ID로 설정합니다.
user1027167

4
아니요, 귀하의 답변이 저에게 효과적이지 않았습니다. 내부적으로 저장 한 가장 높은 ID로 계속 증가했습니다. 내 경우에는 "RESEED, 18"을 명시 적으로 사용하여 다음 ID로 "19"를 가져와야했습니다. 그것이 없으면 "29"에서 계속 증가합니다.
Matthis Kohli

ID 값이 열의 최대 값보다 낮은 경우 DBCC CHECKIDENT (table_name) 만 시드를 변경합니다 . 따라서 @MatthisKohli 사례와 같이 ID 값이 이미 큰 경우 명시 적 시드를 호출해야합니다.
Martheen

82
DBCC CHECKIDENT('databasename.dbo.tablename', RESEED, number)

number = 0이면 다음 삽입에서 자동 증분 필드에 값 1이 포함됩니다.

number = 101이면 다음 삽입에서 자동 증분 필드에 값 102가 포함됩니다.


몇 가지 추가 정보가 ... 당신에게 도움이 될 수 있습니다

자동 증가를 제공하기 전에 number위의 질의에, 당신은 확실히 기존 테이블의 자동 증가 열이 덜 그 값을 포함 할 수 있도록해야한다 number.

테이블 (table1)에서 열 (column_name)의 최대 값을 얻으려면 다음 쿼리를 사용할 수 있습니다

 SELECT MAX(column_name) FROM table1

37

반 바보 증거 :

declare @max int;  
select @max = max(key) from table;  
dbcc checkident(table,reseed,@max)

http://sqlserverplanet.com/tsql/using-dbcc-checkident-to-reseed-a-table-after-delete


1
"DBCC CHECKIDENT (table_name)"도 동일합니다 (경쟁 조건없이 가능)
user1027167

2
@ user1027167 문서에서 '테이블의 현재 ID 값이 ID 열에 저장된 최대 ID 값보다 작은 경우'라고 말합니다. 데이터가 삭제 된 후 정리를 다루지 않습니다 (ID 재사용-종종 나쁜 생각). SQL 2008에서 확인
user423430

1
가장 체계적이고 자동적 인 답변. 브라보!
Mehdi Khademloo

11

MySQL을 사용하는 경우 다음을 시도하십시오.

ALTER TABLE tablename AUTO_INCREMENT = 1

3
이것은 MySQL에 대한 답변입니다. OP는 MSSQL에 대해 묻고 있습니다.
개정

문제는 MS SQL Server에 관한 것입니다
Saher Ahwal

6

데이터베이스의 모든 테이블을 삭제하고 다시 시드하십시오.

    USE [DatabaseName]
    EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all"       -- Disable All the constraints
    EXEC sp_MSForEachTable "DELETE FROM ?"    -- Delete All the Table data
    Exec sp_MSforeachtable 'DBCC CHECKIDENT(''?'', RESEED, 0)' -- Reseed All the table to 0
    Exec sp_msforeachtable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"  -- Enable All  the constraints back

-- You may ignore the errors that shows the table without Auto increment field.

6

나는 그것을 알아. 이것의:

 DBCC CHECKIDENT ('tablename', RESEED, newseed)

4

전체 스키마 자격을 갖춘 유사한 문제가 발생한 사람들을 위해 허용 된 답변을 기반으로합니다.

( [MyDataBase].[MySchemaName].[MyTable]) ... 오류가 발생합니다. 해당 DB의 컨텍스트에 있어야합니다.

즉, 다음과 같은 오류가 발생합니다.

DBCC CHECKIDENT ([MyDataBase].[MySchemaName].[MyTable], RESEED, 0)

정규화 된 테이블 이름을 작은 따옴표로 묶으십시오.

DBCC CHECKIDENT ('[MyDataBase].[MySchemaName].[MyTable]', RESEED, 0)

4

다음과 같은 문장을 사용하는 것이 좋습니다.

DBCC CHECKIDENT (mytable, RESEED, 0)

그러나 OP는 "일부 레코드를 삭제했습니다"라고 말했는데 모두 해당되지 않을 수 있으므로 0 값이 항상 올바른 것은 아닙니다. 또 다른 대답은 자동으로 최대 현재 값을 찾아 그 값으로 다시 시드하도록 제안했지만 테이블에 레코드가 없으면 문제가 발생하므로 max ()는 NULL을 반환합니다. 간단히 사용하여 제안 된 의견

DBCC CHECKIDENT (mytable)

값을 재설정하기 위해 다른 의견에서는 테이블의 값을 이미 최대 값까지만 증가 시킨다고 올바르게 언급했습니다. 이 값이 이미 표의 최대 값보다 높은 경우에는 값을 줄이지 않습니다. 이것이 OP가 원했던 것입니다.

더 나은 솔루션은 이러한 아이디어를 결합합니다. 첫 번째 CHECKIDENT는 값을 0으로 재설정하고 두 번째 CHECKIDENT는 테이블에 레코드가있는 경우 현재 테이블에있는 가장 높은 값으로 재설정합니다.

DBCC CHECKIDENT (mytable, RESEED, 0)
DBCC CHECKIDENT (mytable)

여러 주석이 표시했듯이 다른 테이블에 삭제 된 레코드를 가리키는 외래 키가 없는지 확인하십시오. 그렇지 않으면 해당 외래 키는 테이블을 다시 시드 한 후 생성 한 레코드를 가리키게되며 이는 거의 확실하지 않습니다.


4

DBCC CHECKIDENT테이블에 스키마를 사용할 때 -approach가 제품 문제를 일으키기 때문에이 답변을 추가하고 싶습니다 . 이것을 사용하여 확인하십시오 :

DECLARE @Table AS NVARCHAR(500) = 'myschema.mytable';
DBCC CHECKIDENT (@Table, RESEED, 0);

작업의 성공 여부를 확인하려면

SELECT IDENT_CURRENT(@Table);

0위의 예제에서 출력되어야합니다 .


1

이 작업은 일반적으로 원하지 않습니다. Reseed는 데이터 무결성 문제를 일으킬 수 있습니다. 실제로 모든 테스트 데이터를 지우고 다시 시작하는 개발 시스템에서만 사용됩니다. 모든 관련 레코드가 삭제되지 않은 경우 프로덕션 시스템에서 사용해서는 안됩니다 (외래 키 관계에 있어야하는 모든 테이블이 아닙니다!). 이 작업을 수행하는 엉망을 만들 수 있습니다. 특히 삭제 할 때마다 정기적으로하려는 경우 특히 그렇습니다. ID 필드 값의 차이에 대해 걱정하는 것은 좋지 않습니다.


6
나는 항상 그것을 사용하지 않을 것이며 테스트 데이터베이스에서만 사용되었습니다.
jumbojs

0

이건 어때?

ALTER TABLE `table_name`
  MODIFY `id` int(12) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=0;

자동 증분을 0 또는 원하는 숫자로 변경하는 빠르고 간단한 방법입니다. 데이터베이스를 내보내고 코드를 직접 읽음으로써 이것을 알아 냈습니다.

다음과 같이 작성하여 단일 행 솔루션으로 만들 수도 있습니다.

ALTER TABLE `table_name` MODIFY `id` int(12) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=0;

1
이 코드 스 니펫은 제한적이고 즉각적인 도움이 될 수 있습니다. 적절한 설명은 크게 장기 가치를 향상 할 보여줌으로써 이 문제에 대한 좋은 해결책이고, 다른 유사한 질문을 미래의 독자들에게 더 유용 할 것입니다. 제발 편집 당신이 만든 가정 등 일부 설명을 추가 할 답변을.
Goodbye StackExchange 2018 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.