SQL Server fiziksel olarak bir tablo için KİMLİK DEĞERİ'ni depolar?


12

Birisinin beni bu konuda doğru yöne yönlendirebileceğini umuyorum. İşte şimdiye kadar yaptığım çalışmalar.

SELECT * FROM sys.identity_columns"last_value" değerini veren bir sistem görünümüdür, ancak bu görünümün tanımı dahili bir işlev kullanır IdentityProperty(colName, 'LastValue')- bu bir çıkmaza (orada bir sistem tablosundan çekmemekte).

İnternetteki her yerde (baktım) DBCC IDENT_..., değeri ortaya çıkarmak için komutları kullanmanızı önerir , ancak bu beni gerçekten depolandığı yerde karanlıkta bırakır.

Bu yüzden, tek tek sayfaları DBCC PAGE(TestDB,1,1325,3)test RESEEDkoşumum db'ye karşı arayarak ve 10 ve 12 değerleri arasında yeniden düzenleme komutunu kullanarak geldim .

Bunu yaparken, ben onaltılık değerleri fark IAM: Header, IAM: Single Page Allocationsve IAM: Extent Alloc Status Slot 1her şey değişti. (Ve yine de kendiliğinden kademeli olarak değişen bUse1 değeri ile periyodik olarak değiştiklerini fark ettiler ).

Yani başka bir çıkmaz sokak ve ben fikirlerim bitti. Başka nerede arama yapabilirim?

SQL Server 2014 kullanıyorum. Dahili bilgiler için doyumsuz bir susuzluğum var ve henüz bu kadar zor bir şeyle karşılaşmadım. Dikkatimi çekti, çünkü teoride, (mutlak bir değer) bir yerde saklanıyor ve (tartışmalı olarak) yerleştirilebilir olmalı. Dahili olarak depolanan verilerin / meta verilerin konumlarını ortaya çıkarma arayışımda, bu özel değer beni özellikle zor buluyor. Birisinin gelip bana söyleyeceğini tahmin ediyorum / umuyorum, anlayabilirsin DBCC PAGEama yanlış yere bakıyordum.

Yanıtlar:


8

DAC'ye ( Adanmış Yönetici Konsolu ) erişebiliyorsanız INT, içindeki idtvalsütuna bakarak kimlik sütununun değerini sütunlar için inceleyebilirsiniz sys.syscolpars.

Sayesinde Martin Smith bu tabloya beni yönlendirmeye yönelik bu çok yararlı cevap aracılığı ile Roi Gavish burada ilgili soru üzerine.

Örneğin, aşağıdaki geçici tabloyu ele alalım:

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;

Tablonun ne içerdiğini görelim:

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

Kimlik değeri şu kodla denetlenebilir:

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

İçin BIGINTkimlik sütunlarının, biz gibi kod kullanılan bazı değişkenlerin, boyutunu genişletmek gerekir:

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

Şunun için sonuçlar BIGINT:

+----------------------+
| CurrentIdentityValue |
+----------------------+
|                      |
| 9223372036854775704  |
+----------------------+
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.