SQL Server는 실제로 테이블의 IDENTITY VALUE를 어디에 저장합니까?


12

나는 누군가가 이것에 대해 올바른 방향으로 나를 가리킬 수 있기를 바랍니다. 여기까지 내 작업이 있습니다.

SELECT * FROM sys.identity_columns"last_value"를 제공하는 시스템 뷰이지만 해당 뷰에 대한 정의는 내부 함수를 사용 IdentityProperty(colName, 'LastValue')하므로 막 다른 골목입니다 (시스템 테이블에서 가져 오지 않음).

인터넷의 모든 곳에서 (내가 본 것)은 DBCC IDENT_...명령을 사용하여 가치를 밝힐 것을 제안 하지만 실제로는 그것이 실제로 저장된 위치에 대해 어둠 속에 남아 있습니다.

그래서 DBCC PAGE(TestDB,1,1325,3)테스트 하네스 DB를 사용하여 개별 페이지를 검색 하고 RESEED명령을 사용하여 값 10과 12 사이에서 다시 시드했습니다.

이 과정에서, 나는의 16 진수 값을주의 IAM: Header, IAM: Single Page Allocations그리고 IAM: Extent Alloc Status Slot 1모든이 변경되었습니다. (그리고 그것들 은 자체적으로 점진적으로 변하는 bUse1 값 과 함께 어쨌든 주기적으로 변한다는 것을 깨달았 습니다).

그래서 또 다른 막 다른 골목과 나는 아이디어가 없습니다. 다른 곳에서 검색 할 수 있습니까?

SQL Server 2014를 실행하고 있습니다. 내부 지식에 대한 갈망이 있지만 아직 이처럼 어려운 것은 없습니다. 이론 상으로는 (절대적인 값) 어딘가에 저장되어 있고 (논쟁 적으로) 찾을 수 있어야하기 때문에 내 관심을 끌었습니다. 내부적으로 저장된 데이터 / 메타 데이터의 위치를 ​​찾으려고 노력하면서이 특정 가치는 특히 애매 모호합니다. 나는 누군가가 와서 말해 줄 것이라고 추측 / 호핑하고 있습니다. 당신은 그것을 얻을 수 DBCC PAGE있지만 잘못된 곳을 찾고있었습니다.

답변:


8

당신이 DAC (액세스 할 수있는 경우 전용 관리자 콘솔을 ), 당신을 위해, 식별 컬럼의 값을 검사 할 수 있습니다 INT보고, 열 idtval에서 열 sys.syscolpars.

관련 질문에 대한 Roi Gavish의 유용한 답변통해 저를 그 테이블로 안내해 주신 Martin Smith 에게 감사드립니다 .

예를 들어 다음 임시 테이블을 보자.

USE tempdb;

CREATE TABLE #d
(
    ID INT NOT NULL IDENTITY(1,1)
);

TRUNCATE TABLE #d;

DBCC CHECKIDENT ('#d',RESEED, 2147483635);

INSERT INTO #d DEFAULT VALUES;

테이블에 무엇이 포함되어 있는지 봅시다 :

SELECT *
FROM #d;
+------------+
| ID         |
+------------+
| 2147483635 |
+------------+

이 코드로 식별 값을 검사 할 수 있습니다.

DECLARE @idtval VARBINARY(64);

SELECT @idtval = scp.idtval
FROM sys.syscolpars scp
    INNER JOIN sys.objects o ON scp.id = o.object_id
WHERE o.name LIKE '#d____%'

DECLARE @LittleEndian NVARCHAR(10);
SET @LittleEndian = LEFT(sys.fn_varbintohexstr(@idtval), 10);
SELECT @LittleEndian;
DECLARE @BigEndian NVARCHAR(10) = '0x';
DECLARE @Loop INT = 0;
WHILE @Loop < 4
BEGIN
  SET @BigEndian = @BigEndian + SUBSTRING(@LittleEndian, ((4 - @Loop) * 2) + 1, 2);
  SET @Loop += 1;
END
SELECT CurrentIdentityValue = CONVERT(INT, 
    CONVERT(VARBINARY(32), @BigEndian, 1), 2);
+----------------------+
| CurrentIdentityValue |
+----------------------+
|                      |
| 2147483635           |
+----------------------+

를 들어 BIGINTID 열, 우리는 다음과 같은 코드에서 사용되는 일부 변수의 크기를 확장 할 필요가 :

CREATE TABLE #dBig
(
    ID BIGINT NOT NULL IDENTITY(1,1)
);

TRUNCATE TABLE #dBig;

DBCC CHECKIDENT ('#dBig',RESEED, 9223372036854775704);

INSERT INTO #dBig DEFAULT VALUES;

SELECT *
FROM #dBig;


DECLARE @idtval VARBINARY(64);

SELECT @idtval = scp.idtval
FROM sys.syscolpars scp
    INNER JOIN sys.objects o ON scp.id = o.object_id
WHERE o.name LIKE '#dBig____%'

DECLARE @LittleEndian NVARCHAR(18);
SET @LittleEndian = LEFT(sys.fn_varbintohexstr(@idtval), 18);
DECLARE @BigEndian NVARCHAR(18) = '0x';
DECLARE @Loop INT = 0;
WHILE @Loop < 8
BEGIN
  SET @BigEndian = @BigEndian + SUBSTRING(@LittleEndian, ((8 - @Loop) * 2) + 1, 2);
  SET @Loop += 1;
END
SELECT CurrentIdentityValue = CONVERT(BIGINT, 
    CONVERT(VARBINARY(32), @BigEndian, 1), 2);

에 대한 결과 BIGINT:

+----------------------+
| CurrentIdentityValue |
+----------------------+
|                      |
| 9223372036854775704  |
+----------------------+
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.