SQL Server เก็บค่าความเป็นตัวตนของตารางไว้ที่ใด


12

ฉันหวังว่าบางคนสามารถชี้ฉันไปในทิศทางที่ถูกต้องในอันนี้ นี่คือผลงานของฉันจนถึงตอนนี้

SELECT * FROM sys.identity_columnsคือมุมมองระบบที่ให้ "last_value" แต่คำจำกัดความสำหรับมุมมองนั้นใช้ฟังก์ชันภายในIdentityProperty(colName, 'LastValue')- นั่นคือจุดสิ้นสุด (ไม่ดึงออกจากตารางระบบที่นั่น)

ทุกที่ (ฉันดู) บนอินเทอร์เน็ตแนะนำให้ใช้DBCC IDENT_...คำสั่งเพื่อเปิดเผยค่า แต่ก็ยังทำให้ฉันอยู่ในที่มืดราวกับว่ามันถูกเก็บไว้ที่ไหน

ดังนั้นฉันมาถึงการค้นหาหน้าเว็บแต่ละหน้าพร้อมDBCC PAGE(TestDB,1,1325,3)กับชุดทดสอบฐานข้อมูลของฉันและการใช้RESEEDคำสั่งเพื่อดำเนินการระหว่างค่า 10 และ 12

ในการนี้ผมสังเกตเห็นค่าฐานสิบหกบนIAM: Header, IAM: Single Page AllocationsและIAM: Extent Alloc Status Slot 1การเปลี่ยนแปลงทั้งหมด (และตระหนักว่าพวกเขามีการเปลี่ยนแปลงเป็นระยะอยู่แล้วพร้อมกับค่าbUse1ซึ่งการเปลี่ยนแปลงที่เพิ่มขึ้นด้วยตัวเองเช่นกัน)

ดังนั้นจุดจบอื่นและฉันหมดความคิด ฉันสามารถค้นหาได้ที่ไหน

ฉันใช้ SQL Server 2014 ฉันมีความกระหายที่ไม่รู้จักพอสำหรับความรู้ภายในและยังไม่เจออะไรที่เข้าใจยากเช่นนี้ มันดึงดูดความสนใจของฉันได้เพราะในทางทฤษฎีแล้วมัน (ค่าสัมบูรณ์) ถูกเก็บไว้ที่ไหนสักแห่งและควรระบุตำแหน่ง (เนื้อหา) ในการสืบเสาะหาที่ตั้งของข้อมูล / เมตาดาต้าที่เก็บไว้ภายในค่านี้จะทำให้ฉันเข้าใจยากเป็นพิเศษ ฉันคาดเดา / หวังว่าจะมีใครบางคนเข้ามาและบอกฉันคุณสามารถเอามันไปด้วยDBCC PAGEแต่ฉันกำลังมองหาที่ผิด

คำตอบ:


8

หากคุณสามารถเข้าถึง DAC ( เฉพาะคอนโซลการดูแล ) คุณสามารถตรวจสอบค่าของคอลัมน์ประจำตัวสำหรับINTคอลัมน์โดยดูที่คอลัมน์idtvalsys.syscolpars

ขอขอบคุณมาร์ตินสมิ ธ ที่นำฉันไปที่ตารางผ่านคำตอบที่มีประโยชน์มากนี้โดยร้อยเอ็ด 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  |
+----------------------+
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.