Де SQL Server фізично зберігає значення Ідентичності для таблиці?


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

Якщо ви можете отримати доступ до ЦАП ( виділеної консолі адміністратора ), ви можете перевірити значення стовпця ідентичності для 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.