Gdzie SQL Server fizycznie przechowuje WARTOŚĆ TOŻSAMOŚCI dla tabeli?

12

Mam nadzieję, że ktoś może skierować mnie w tym kierunku. Oto moje dotychczasowe działania.

SELECT * FROM sys.identity_columnsjest widokiem systemu, który daje „ostatnią wartość”, ale definicja tego widoku używa funkcji wewnętrznej IdentityProperty(colName, 'LastValue')- więc to ślepy zaułek (nie wyciąganie go z tabeli systemowej).

Wszędzie (szukałem) w Internecie sugeruje użycie DBCC IDENT_...poleceń, aby odkryć wartość, ale to wciąż pozostawia mnie w ciemności co do tego, gdzie jest faktycznie przechowywana.

Doszedłem więc do przeszukiwania poszczególnych stron za pomocą DBCC PAGE(TestDB,1,1325,3)mojej wiązki testowej db i użycia RESEEDpolecenia do ponownego wyboru między wartościami 10 i 12.

W ten sposób, zauważyłem wartości hex na IAM: Header, IAM: Single Page Allocationsi IAM: Extent Alloc Status Slot 1wszystko się zmieniło. (I zdali sobie sprawę, że i tak zmieniają się okresowo wraz z wartością bUse1, która sama również zmienia się stopniowo).

Więc kolejny ślepy zaułek i nie mam pomysłów. Gdzie jeszcze mogę szukać?

Korzystam z programu SQL Server 2014. Mam nienasycone pragnienie wewnętrznej wiedzy i jeszcze nie spotkałem się z czymś tak nieuchwytnym jak to. Przyciągnęło to moją uwagę, ponieważ teoretycznie (wartość bezwzględna) jest gdzieś przechowywana i powinna (prawdopodobnie) być zlokalizowana. W mojej próbie odkrycia lokalizacji wewnętrznie przechowywanych danych / metadanych ta szczególna wartość wydaje mi się szczególnie nieuchwytna. Zgaduję / mam nadzieję, że ktoś przyjdzie i powie mi, że możesz to załatwić, DBCC PAGEale szukałem w złym miejscu.

Simon Jones
źródło

Odpowiedzi:

8

Jeśli masz dostęp do DAC ( dedykowanej konsoli administratora ), możesz sprawdzić wartość kolumny tożsamości dla INTkolumn, patrząc na idtvalkolumnę w sys.syscolpars.

Dzięki Martin Smith o skierowanie mnie do tej tabeli za pośrednictwem tej bardzo użytecznej odpowiedzi przez Roi Gavish na powiązane pytanie tutaj.

Weźmy na przykład następującą tabelę tymczasową:

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;

Zobaczmy, co zawiera tabela:

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

Wartość tożsamości można sprawdzić za pomocą tego kodu:

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           |
+----------------------+

W przypadku BIGINTkolumn tożsamości musimy zwiększyć rozmiar niektórych zmiennych używanych w kodzie, takich jak:

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

Wyniki dla BIGINT:

+----------------------+
| CurrentIdentityValue |
+----------------------+
|                      |
| 9223372036854775704  |
+----------------------+
Max Vernon
źródło