programing

DBCC CHECKIDENT가 ID를 0으로 설정하다

css3 2023. 4. 15. 09:12

DBCC CHECKIDENT가 ID를 0으로 설정하다

테이블에서 ID를 재설정하기 위해 이 코드를 사용합니다.

DBCC CHECKIDENT('TableName', RESEED, 0)

이것은 대부분의 경우 정상적으로 동작하며 첫 번째 삽입은 Id 열에 1을 삽입합니다.단, 작성한 스크립트를 사용하여 DB를 삭제하고 다시 작성한 후 DBCC CHECKIDENT를 호출하면 처음 삽입된 항목의 ID는 0이 됩니다.

좋은 생각 있어요?

EDIT: 조사 결과 매뉴얼을 제대로 읽지 않은 것을 알게 되었습니다.현재 ID 값은 new_reseed_value로 설정되어 있습니다.테이블 작성 후 테이블에 행을 삽입하지 않은 경우 DBCC CHECKIDENT 실행 후 삽입된 첫 번째 행은 new_reseed_value를 ID로 사용합니다.그렇지 않으면 삽입된 다음 행은 new_reseed_value + 1을 사용합니다.

질문의 편집에 쓴 내용은 당신이 옳습니다.

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

솔루션은 다음 스크립트에 기재되어 있습니다.그것은 일종의 poor-man-truncate 입니다.

-- 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);

질문에서 지적하신 바와 같이 이는 문서화된 행동입니다.그래도 이상해요.테스트 데이터베이스를 재입력하고 있는데, ID 필드의 값에 의존하지 않아도 데이터베이스를 처음 작성할 때와 모든 데이터를 삭제하고 다시 입력한 후에 값이 달라서 조금 귀찮았습니다.

가능한 해결책은 삭제 대신 잘라내기를 사용하여 테이블을 청소하는 것입니다.그 후 모든 제약을 해제하고 나중에 다시 작성해야 합니다.

이렇게 하면 항상 새로 작성된 테이블로 동작하며 DBCC CHECKIDENT를 호출할 필요가 없습니다.첫 번째 ID 값은 테이블 정의에 지정된 값으로, 데이터를 처음 삽입하든 N번째 삽입하든 동일합니다.

테이블에 레코드가 삽입되어 있는지 여부에 대한 두 가지 경우를 모두 커버하기 위해 하나의 명령어로 ID 열을 설정/리셋할 수 없다는 것은 말도 안 되는 일입니다.SO에서 우연히 이 질문을 하기 전까지는 제가 겪고 있는 행동을 이해할 수 없었습니다.

저의 솔루션(어색하지만 기능)은 다음과 같이 명시적으로 체크하는 것입니다.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

스테이트먼트를 다음으로 변경

  DBCC CHECKIDENT('TableName', RESEED, 1)

이 값은 2(또는 테이블을 다시 작성할 경우 1)부터 시작되지만 0은 되지 않습니다.

첫 번째 아이덴티티 컬럼을 0으로 하고 동작하기 때문에 값을 0으로 리셋하기 위한 실험으로 이 작업을 수행했습니다.

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

자세한 것은 이쪽도 참조해 주세요.http://sqlblog.com/blogs/alexander_kuznetsov/archive/2008/06/26/fun-with-dbcc-chekident.aspx

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

SQL에서 ID를 특정 값으로 설정하기 위해 다음과 같이 사용하고 있습니다.-

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

Zyphrax의 대답을 빌려서...

USE DatabaseName

DECLARE @ReseedBit BIT = 
    COALESCE((SELECT SUM(CONVERT(BIGINT, ic.last_value))
                FROM sys.identity_columns ic
                INNER JOIN sys.tables t ON ic.object_id = t.object_id), 0)
DECLARE @Reseed INT = 
CASE 
    WHEN @ReseedBit = 0 THEN 1 
    WHEN @ReseedBit = 1 THEN 0 
END

DBCC CHECKIDENT ('dbo.table_name', RESEED, @Reseed);

경고:이는 DB가 열거형 정의 테이블로 초기화되는 참조 데이터 입력 상황에서 사용하기 위한 것입니다. 여기서 해당 테이블의 ID 값은 항상 1에서 시작해야 합니다.처음 DB를 생성할 때(SSDT-DB 퍼블리싱 중 등) @Reseed는 0이어야 하지만 데이터를 리셋하고 다시 삽입하는 경우 @Reseed는 1이어야 합니다.따라서 이 코드는 수동으로 호출할 수 있지만 SSDT-DB 프로젝트의 배포 후 스크립트에서 호출할 수도 있는 DB 데이터를 재설정하기 위한 저장 프로시저에서 사용하기 위한 것입니다.이와 같이 참조 데이터 삽입물은 한 곳에서만 정의되며 게시 시 배포 후에만 사용하도록 제한되지 않습니다. 또한 저장된 프로시저를 호출하여 DB를 알려진 정상 상태로 재설정함으로써 나중에 사용할 수 있습니다(개발 및 자동 테스트 지원 등).

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