Где SQL Server физически хранит значение IDENTITY для таблицы?


12

Я надеюсь, что кто-то может указать мне правильное направление на этот. Вот мои разработки до сих пор.

SELECT * FROM sys.identity_columnsэто системное представление, которое дает «last_value», но определение для этого представления использует внутреннюю функцию IdentityProperty(colName, 'LastValue')- так что это тупик (не вытаскивая его из системной таблицы).

Везде (я смотрел) в Интернете предлагается использовать DBCC IDENT_...команды для раскрытия значения, но это все еще оставляет меня в неведении относительно того, где оно на самом деле хранится.

Итак, я пришел к поиску отдельных страниц с помощью DBCC PAGE(TestDB,1,1325,3)моего тестового жгута db и использовал RESEEDкоманду для повторного заполнения между значениями 10 и 12.

При этом я заметил шестнадцатеричные значения на 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 на соответствующий вопрос здесь.

Возьмите, например, следующую временную таблицу:

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

Для BIGINTстолбцов идентификаторов нам нужно расширить размер некоторых переменных, используемых в коде, таких как:

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  |
+----------------------+
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.