Programing

DBCC CHECKIDENT는 ID를 0으로 설정합니다.

lottogame 2020. 11. 12. 07:39
반응형

DBCC CHECKIDENT는 ID를 0으로 설정합니다.


이 코드를 사용하여 테이블의 ID를 재설정합니다.

DBCC CHECKIDENT('TableName', RESEED, 0)

이것은 대부분의 경우 잘 작동하며 첫 번째 삽입에서 Id 열에 1을 삽입합니다. 그러나 db를 삭제하고 다시 만든 다음 (내가 작성한 스크립트를 사용하여) DBCC CHECKIDENT를 호출하면 삽입 된 첫 번째 항목의 ID는 0이됩니다.

어떤 아이디어?

편집 : 조사 후 문서를 제대로 읽지 못했다는 사실을 발견했습니다. http://msdn.microsoft.com/en-us/library/aa258817(SQL.80).aspx- "현재 ID 값은 new_reseed_value. 생성 된 이후 테이블에 삽입 된 행이없는 경우 DBCC CHECKIDENT 실행 후 삽입 된 첫 번째 행은 new_reseed_value를 ID로 사용합니다. 그렇지 않으면 삽입 된 다음 행은 new_reseed_value + 1을 사용합니다. "


질문에서 지적했듯이 문서화 된 행동 입니다. 그래도 여전히 이상합니다. 나는 테스트 데이터베이스를 다시 채우는 데 사용하며 ID 필드의 값에 의존하지 않지만 처음부터 데이터베이스를 처음부터 채울 때와 모든 데이터를 제거하고 다시 채울 때 다른 값을 갖는 것이 약간 귀찮습니다.

가능한 해결책은 삭제 대신 잘라내기를 사용 하여 테이블을 정리하는 것입니다. 하지만 그런 다음 모든 제약 조건을 삭제하고 나중에 다시 만들어야합니다.

이러한 방식으로 항상 새로 생성 된 테이블로 동작하며 DBCC CHECKIDENT를 호출 할 필요가 없습니다. 첫 번째 ID 값은 테이블 정의에 지정된 값이되며 데이터를 처음 삽입하거나 N 번째 데이터를 삽입해도 동일합니다.


질문을 편집 할 때 작성한 내용이 맞습니다.

실행 후 DBCC CHECKIDENT('TableName', RESEED, 0):
-새로 생성 된 테이블은 ID 0으로 시작합니다
.-기존 테이블은 ID 1로 계속됩니다.

해결책은 아래 스크립트에 있으며 일종의 가난한 사람이 잘립니다. :)

-- Remove all records from the Table
DELETE FROM TableName

-- Use sys.identity_columns to see if there was a last known identity value
-- for the Table. If there was one, the Table is not new and needs a reset
IF EXISTS (SELECT * FROM sys.identity_columns WHERE OBJECT_NAME(OBJECT_ID) = 'TableName' AND last_value IS NOT NULL) 
    DBCC CHECKIDENT (TableName, RESEED, 0);

문을 다음으로 변경

  DBCC CHECKIDENT('TableName', RESEED, 1)

이것은 2 (또는 테이블을 다시 만들 때 1)에서 시작하지만 0이되지는 않습니다.


첫 번째 ID 열이 0이 되길 원하고 작동 중이므로 값을 0으로 재설정하는 실험으로 이것을 수행했습니다.

dbcc CHECKIDENT(MOVIE,RESEED,0)
dbcc CHECKIDENT(MOVIE,RESEED,-1)
DBCC CHECKIDENT(MOVIE,NORESEED)

테이블에 레코드가 삽입되었는지 여부에 대한 두 경우를 모두 처리하기 위해 단일 명령으로 ID 열을 설정 / 재설정 할 수 없다는 것은 우스꽝스러워 보입니다. 나는이 질문을 우연히 발견 할 때까지 내가 경험 한 행동을 이해할 수 없었습니다!

내 솔루션 (추악하지만 작동 함)은 sys.identity_columns.last_value테이블 (테이블에 레코드가 삽입되었는지 여부를 알려줌 )을 명시 적으로 확인하고 DBCC CHECKIDENT각 경우에 적절한 명령을 호출하는 것 입니다. 다음과 같습니다.

DECLARE @last_value INT = CONVERT(INT, (SELECT last_value FROM sys.identity_columns WHERE OBJECT_NAME(OBJECT_ID) = 'MyTable'));
IF @last_value IS NULL
    BEGIN
        -- Table newly created and no rows inserted yet; start the IDs off from 1
        DBCC CHECKIDENT ('MyTable', RESEED, 1);
    END
ELSE
    BEGIN
        -- Table has rows; ensure the IDs continue from the last ID used
        DECLARE @lastValUsed INT = (SELECT ISNULL(MAX(ID),0) FROM MyTable);
        DBCC CHECKIDENT ('MyTable', RESEED, @lastValUsed);
    END

여기도 참조하십시오 : http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/06/26/fun-with-dbcc-chekident.aspx

이것은 문서화 된 동작입니다. 테이블을 다시 생성하는 경우 CHECKIDENT를 실행하는 이유는이 경우 단계를 건너 뛰거나 TRUNCATE를 사용합니다 (FK 관계가없는 경우).


SQL에서 이것을 사용하여 IDENTITY를 특정 값으로 설정했습니다.

DECLARE @ID int = 42;
DECLARE @TABLENAME  varchar(50) = 'tablename'

DECLARE @SQL nvarchar(1000) = 'IF EXISTS (SELECT * FROM sys.identity_columns WHERE OBJECT_NAME(OBJECT_ID) = '''+@TABLENAME+''' AND last_value IS NOT NULL)
    BEGIN
        DBCC CHECKIDENT('+@TABLENAME+', RESEED,' + CONVERT(VARCHAR(10),@ID-1)+');
    END
    ELSE
    BEGIN
        DBCC CHECKIDENT('+@TABLENAME+', RESEED,' + CONVERT(VARCHAR(10),@ID)+');
    END';
EXEC (@SQL);

그리고 이것은 C #에서 특정 값을 설정합니다.

SetIdentity(context, "tablename", 42);
.
.
private static void SetIdentity(DbContext context, string table,int id)
{
    string str = "IF EXISTS (SELECT * FROM sys.identity_columns WHERE OBJECT_NAME(OBJECT_ID) = '" + table
        + "' AND last_value IS NOT NULL)\nBEGIN\n";
    str += "DBCC CHECKIDENT('" + table + "', RESEED," + (id - 1).ToString() + ");\n";
    str += "END\nELSE\nBEGIN\n";
    str += "DBCC CHECKIDENT('" + table + "', RESEED," + (id).ToString() + ");\n";
    str += "END\n";
    context.Database.ExecuteSqlCommand(str);
}

이것은 위의 답변을 기반으로하며 항상 다음 값이 42 (이 경우)인지 확인합니다.


다음과 같이하십시오.

IF EXISTS (SELECT * FROM tablename)
BEGIN
    DELETE from  tablename
    DBCC checkident ('tablename', reseed, 0)
END

USE AdventureWorks2012;  
GO  
DBCC CHECKIDENT ('Person.AddressType', RESEED, 0);  
GO 



AdventureWorks2012=Your databasename
Person.AddressType=Your tablename

참고 URL : https://stackoverflow.com/questions/472578/dbcc-checkident-sets-identity-to-0

반응형