Sql-Server

SQL Server 將表的 IDENTITY VALUE 物理儲存在哪裡?

  • April 21, 2016

我希望有人能在這個問題上指出我正確的方向。這是我到目前為止的工作。

SELECT * FROM sys.identity_columns是一個系統視圖,它提供“last_value”,但該視圖的定義使用內部函式IdentityProperty(colName, 'LastValue')- 所以這是一個死胡同(不是從那裡的系統表中拉出來的)。

網際網路上的任何地方(我看過)都建議使用DBCC IDENT_...命令來發現價值,但這仍然讓我對它的實際儲存位置一無所知。

DBCC PAGE(TestDB,1,1325,3)因此,我開始使用我的測試工具 db搜尋各個頁面,並使用RESEED命令在值 10 和 12 之間重新設置種子。

在這樣做時,我注意到 , 上的十六進制值IAM: HeaderIAM: Single Page Allocations發生IAM: Extent Alloc Status Slot 1了變化。(並意識到它們會隨著bUse1值的變化而周期性變化,bUse1 值也會自行遞增)。

所以另一個死胡同,我完全沒有想法。我還能在哪裡搜尋?

我正在執行 SQL Server 2014。我對內部知識有著永不滿足的渴望,並且還沒有遇到像這樣難以捉摸的東西。它引起了我的注意,因為從理論上講,它(絕對值)儲存在某個地方並且應該(可以說)是可定位的。在我尋找內部儲存數據/元數據位置的過程中,這個特殊的價值讓我覺得特別難以捉摸。我猜/希望有人會過來告訴我,你可以得到它,DBCC PAGE但我找錯地方了。

如果您可以訪問 DAC(專用管理員控制台INT),則可以通過查看 中的idtval列來檢查列的標識列的值sys.syscolpars

感謝Martin Smith通過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  |
+----------------------+

引用自:https://dba.stackexchange.com/questions/135950