Di mana SQL Server secara fisik menyimpan VALENT IDENTITAS untuk tabel?

12

Saya berharap seseorang dapat mengarahkan saya ke arah yang benar untuk hal ini. Inilah pekerjaan saya sejauh ini.

SELECT * FROM sys.identity_columnsadalah tampilan sistem yang memberikan "last_value" tetapi definisi untuk tampilan itu menggunakan fungsi internal IdentityProperty(colName, 'LastValue')- jadi itu jalan buntu (tidak menariknya dari tabel sistem di sana).

Di mana-mana (saya telah melihat) di internet menyarankan menggunakan DBCC IDENT_...perintah untuk mengungkap nilai tetapi itu masih membuat saya dalam kegelapan di mana itu sebenarnya disimpan.

Jadi, saya tiba di mencari halaman individual dengan DBCC PAGE(TestDB,1,1325,3)melawan harness pengujian saya db dan menggunakan RESEEDperintah untuk kembali antara nilai 10 dan 12.

Dalam melakukan ini, saya perhatikan nilai hex pada IAM: Header, IAM: Single Page Allocationsdan IAM: Extent Alloc Status Slot 1semua berubah. (Dan menyadari bahwa mereka berubah secara berkala bersamaan dengan nilai bUse1 yang berubah secara bertahap juga).

Jadi jalan buntu yang lain dan saya kehabisan ide. Di mana lagi saya bisa mencari?

Saya menjalankan SQL Server 2014. Saya sangat haus akan pengetahuan internal dan belum menemukan sesuatu yang sulit dipahami seperti ini. Ini menarik perhatian saya karena secara teori, itu (nilai absolut) disimpan di suatu tempat dan harus (bisa dibilang) dapat dilacak. Dalam pencarian saya untuk menggali lokasi data / meta data yang disimpan secara internal, nilai khusus ini menurut saya sangat sulit dipahami. Saya menduga / berharap seseorang akan datang dan memberi tahu saya, Anda bisa mendapatkannya DBCC PAGEtetapi saya mencari di tempat yang salah.

Simon Jones
sumber

Jawaban:

8

Jika Anda dapat mengakses DAC ( Dedicated Administrator Console ), Anda dapat memeriksa nilai kolom identitas, untuk INTkolom, dengan melihat idtvalkolom di sys.syscolpars.

Terima kasih kepada Martin Smith karena telah mengarahkan saya ke meja itu melalui jawaban yang sangat berguna ini oleh Roi Gavish untuk pertanyaan terkait di sini.

Ambil, misalnya, tabel sementara berikut:

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;

Mari kita lihat isi tabel:

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

Nilai identitas dapat diperiksa dengan kode ini:

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

Untuk BIGINTkolom identitas, kita perlu memperluas ukuran beberapa variabel yang digunakan dalam kode, seperti:

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

Hasil untuk BIGINT:

+----------------------+
| CurrentIdentityValue |
+----------------------+
|                      |
| 9223372036854775704  |
+----------------------+
Max Vernon
sumber