Dove SQL Server memorizza fisicamente il VALORE IDENTITÀ per una tabella?


12

Spero che qualcuno possa indicarmi la giusta direzione su questo. Ecco i miei allenamenti finora.

SELECT * FROM sys.identity_columnsè una vista di sistema che fornisce "last_value" ma la definizione per quella vista utilizza una funzione interna, IdentityProperty(colName, 'LastValue')quindi è un vicolo cieco (non estraendolo da una tabella di sistema).

Ovunque (ho guardato) su Internet suggerisce di usare i DBCC IDENT_...comandi per scoprire il valore, ma questo mi lascia ancora nell'oscurità su dove è effettivamente memorizzato.

Quindi, sono arrivato a cercare le singole pagine con DBCC PAGE(TestDB,1,1325,3)contro il mio cablaggio di test db e usando il RESEEDcomando per ridimensionare tra i valori 10 e 12.

Nel fare questo, ho notato che i valori esadecimali sul IAM: Header, IAM: Single Page Allocationse IAM: Extent Alloc Status Slot 1tutto è cambiato. (E realizzato che cambiano periodicamente comunque insieme al valore bUse1 che cambia anche in modo incrementale da solo).

Quindi un altro vicolo cieco e sono completamente senza idee. Dove altro posso cercare?

Sto eseguendo SQL Server 2014. Ho una sete insaziabile di conoscenza interna e devo ancora imbattermi in qualcosa di così sfuggente. Ha attirato la mia attenzione perché in teoria, (un valore assoluto) è memorizzato da qualche parte e dovrebbe (probabilmente) essere localizzabile. Nella mia ricerca di scoprire posizioni di dati / metadati memorizzati internamente, questo particolare valore mi sembra particolarmente sfuggente. Sto indovinando / sperando che qualcuno venga e me lo dica, puoi farcela DBCC PAGEma stavo guardando nel posto sbagliato.

Risposte:


8

Se è possibile accedere al DAC ( Dedicated Administrator Console ), è possibile controllare il valore della colonna Identity, per le INTcolonne, osservando la idtvalcolonna in sys.syscolpars.

Grazie a Martin Smith per avermi indirizzato a quel tavolo tramite questa utilissima risposta di Roi Gavish su una domanda correlata qui.

Prendi, ad esempio, la seguente tabella temporanea:

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;

Vediamo cosa contiene la tabella:

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

Il valore dell'identità può essere verificato con questo codice:

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

Per le BIGINTcolonne di identità, è necessario espandere la dimensione di alcune variabili utilizzate nel codice, ad esempio:

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

Risultati per BIGINT:

+----------------------+
| CurrentIdentityValue |
+----------------------+
|                      |
| 9223372036854775704  |
+----------------------+
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.