web-dev-qa-db-ja.com

SQL ServerはテーブルのIDENTITY VALUEを物理的にどこに格納しますか?

私は誰かがこれについて正しい方向に私を向けることができることを望んでいます。これが私のこれまでの作業です。

_SELECT * FROM sys.identity_columns_は「last_value」を提供するシステムビューですが、そのビューの定義は内部関数IdentityProperty(colName, 'LastValue')を使用しているため、行き止まりになります(システムテーブルからプルされない)。

インターネット上のどこでも(私が見たところ)、_DBCC IDENT_..._コマンドを使用して値を明らかにすることをお勧めしますが、それでも実際にどこに保存されているのかがわかりません。

そのため、テストハーネスdbに対してDBCC PAGE(TestDB,1,1325,3)を使用して個々のページを検索し、RESEEDコマンドを使用して値10と12の間で再シードしました。

これを行うと、_IAM: Header_、_IAM: Single Page Allocations_、_IAM: Extent Alloc Status Slot 1_の16進値がすべて変更されていることに気付きました。 (そして、それらはとにかく定期的に変化しますbUse1値も一緒に増分的に変化します)。

だからもう一つの行き止まりで、私はすべてアイデアがなくなった。他にどこで検索できますか?

私はSQL Server 2014を実行しています。私は内部の知識に対する飽くなき渇きを抱えており、これほど捉えどころのないものにまだ出会っていません。理論的には(絶対値)はどこかに保存されており、(おそらく)配置可能でなければならないので、私の注目を集めました。内部に保存されているデータ/メタデータの場所を発掘するための私の探求では、この特定の値は、特にわかりにくいと感じます。私は誰かがやって来て教えてくれると思います/期待しています、あなたは_DBCC PAGE_でそれを得ることができますが、私は間違った場所を探していました。

12
Simon Jones

DACにアクセスできる場合( 専用管理者コンソール )、INT列のID列の値を調べるには、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 |
+------------+

ID値は、次のコードで検査できます。

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 ID列の場合、次のように、コードで使用されるいくつかの変数のサイズを拡張する必要があります。

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  |
+----------------------+
8
Max Vernon