J'espère que quelqu'un peut me diriger dans la bonne direction sur celui-ci. Voici mon fonctionnement jusqu'à présent.
SELECT * FROM sys.identity_columns
Est 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 (sans le tirant d'une table de système).
Partout (j'ai regardé) sur Internet suggère d'utiliser DBCC IDENT_...
Commandes de découvrir la valeur mais qui me laisse toujours dans le noir de l'endroit où elle est réellement stockée.
Donc, je suis arrivé à la recherche des pages individuelles avec DBCC PAGE(TestDB,1,1325,3)
contre mon harnais de test DB et à l'aide de la commande RESEED
pour réexécuter entre les valeurs 10 et 12.
Ce faisant, j'ai remarqué les valeurs hexagonales sur le IAM: Header
, IAM: Single Page Allocations
Et IAM: Extent Alloc Status Slot 1
Tout a changé. (Et réalisé qu'ils changent périodiquement de toute façon avec la valeur Buse1 la valeur qui change progressivement par lui-même).
Donc, une autre impasse et je suis tout à fait des idées. Où puis-je rechercher?
Je couronne SQL Server 2014. J'ai une soif insatiable pour la connaissance des internes et je n'ai pas encore rencontré de quoi que ce soit aussi insaisissable que cela. Il a attiré mon attention car en théorie, elle (une valeur absolue) est stockée quelque part et devrait (sans doute) être localisable. Dans ma quête de la découverte des emplacements de données/métadonnées stockées en interne, cette valeur particulière me frappe comme particulièrement insaisissable. Je suppose/espère que quelqu'un va venir et me le dire, vous pouvez l'obtenir avec DBCC PAGE
Mais je cherchais au mauvais endroit.
Si vous pouvez accéder au DAC ( console d'administrateur dédié ), vous pouvez inspecter la valeur de la colonne d'identité pour INT
colonnes, en regardant la colonne idtval
sys.syscolpars
.
Merci à Martin Smith pour me diriger à cette table via cette réponse très utile par ROI Gavish sur une question connexe ici.
Prenez, par exemple, la table temporaire suivante:
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 la table contient:
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 BIGINT
colonnes d'identité, nous devons élargir 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 le BIGINT
:
+----------------------+
| CurrentIdentityValue |
+----------------------+
| |
| 9223372036854775704 |
+----------------------+