Où SQL Server stocke-t-il physiquement la VALEUR D'IDENTITÉ pour une table?


12

J'espère que quelqu'un pourra m'orienter dans la bonne direction sur celui-ci. Voici mes travaux jusqu'à présent.

SELECT * FROM sys.identity_columnsest une vue système qui donne "last_value" mais la définition de cette vue utilise une fonction interne IdentityProperty(colName, 'LastValue')- c'est donc une impasse (ne pas la tirer d'une table système là-bas).

Partout (j'ai regardé) sur Internet suggère d'utiliser des DBCC IDENT_...commandes pour découvrir la valeur mais cela me laisse toujours dans le noir quant à l'endroit où il est réellement stocké.

Donc, je suis arrivé à rechercher les pages individuelles avec DBCC PAGE(TestDB,1,1325,3)mon harnais de test db et à utiliser la RESEEDcommande pour réamorcer entre les valeurs 10 et 12.

Ce faisant, j'ai remarqué les valeurs hexadécimales sur le IAM: Header, IAM: Single Page Allocationset IAM: Extent Alloc Status Slot 1tout a changé. (Et réalisé qu'ils changent de toute façon périodiquement avec la valeur bUse1 qui change également de façon incrémentielle).

Donc une autre impasse et je suis à court d'idées. Où puis-je chercher?

J'exécute SQL Server 2014. J'ai une soif insatiable de connaissances internes et je n'ai encore rien rencontré d'aussi insaisissable. Cela a attiré mon attention parce qu'en théorie, il (une valeur absolue) est stocké quelque part et devrait (sans doute) être localisable. Dans ma quête pour dénicher des emplacements de données / métadonnées stockées en interne, cette valeur particulière me semble particulièrement insaisissable. J'imagine / j'espère que quelqu'un viendra me dire, vous pouvez l'obtenir DBCC PAGEmais je cherchais au mauvais endroit.

Réponses:


8

Si vous pouvez accéder à la DAC ( Dedicated Administrator Console ), vous pouvez inspecter la valeur de la colonne d'identité, pour les INTcolonnes, en consultant la idtvalcolonne dans sys.syscolpars.

Merci à Martin Smith de m'avoir dirigé vers cette table via cette réponse très utile de Roi Gavish sur une question connexe ici.

Prenez, par exemple, le tableau temporaire suivant:

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;

Voyons ce que contient le tableau:

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

La valeur d'identité peut être inspectée par ce code:

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

Pour BIGINTles colonnes d'identité, nous devons augmenter la taille de certaines variables utilisées dans le code, telles que:

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

Résultats pour BIGINT:

+----------------------+
| CurrentIdentityValue |
+----------------------+
|                      |
| 9223372036854775704  |
+----------------------+
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.