Sim*_*nes 12 sql-server database-internals identity sql-server-2014
我希望有人可以为我指出正确的方向。到目前为止,这是我的工作。
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值定期更改,而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;
Run Code Online (Sandbox Code Playgroud)
让我们看看表包含什么:
SELECT *
FROM #d;
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)
可以通过以下代码检查标识值:
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);
Run Code Online (Sandbox Code Playgroud)
SELECT *
FROM #d;
Run Code Online (Sandbox Code Playgroud)
对于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);
Run Code Online (Sandbox Code Playgroud)
结果BIGINT
:
+------------+
| ID |
+------------+
| 2147483635 |
+------------+
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1321 次 |
最近记录: |