Nie od dziś wiadomo, że SQL Server dostarcza sporej liczby niesupportowanych i nieudokumentowanych procedur, funkcji czy komend DBCC. Najnowsza wersja, a konkretnie CTP6, nie odbiega od tej praktyki. Jedną z ciekawszych funkcjonalności tego typu, którą chciałbym zaprezentować, jest
%%physloc%%. Jest to specjalna właściwość systemowa (nazywana także wirtualną kolumną), zwracająca wartość typu
binary(8), która działa wyłącznie w kontekście wiersza. Przy jej pomocy uzyskujemy tzw.
physical row locator, czyli binarnie zapisany RID rekordu:
CREATE TABLE test
(
col int DEFAULT(0)
);
INSERT INTO test DEFAULT VALUES;
SELECT %%physloc%%, col FROM test;
Dostępne są także dwie nieudokumentowane funkcje -
sys.fn_PhysLocFormatter i
sys.fn_PhysLocCracker, które konwertują
%%physloc%% na klasyczny RID. Różnica między wymienionymi funkcjami polega wyłącznie na tym, że pierwsza zwraca wartość skalarną, a druga - jako
table valued function - tabelę (konkretnie - jeden rekord). W dalszych rozważaniach skupie się na pierwszej funkcji.
Fizyczny lokalizator nie jest najbardziej widowiskową funkcjonalnością produkcyjną, ale w głowie prawdziwego SQL developera lub DBA na pewno pojawi się cały szereg pomysłowych jego zastosowań, zwłaszcza podczas zgłębiania tajników storage engine'u, performance testów, czy zabaw z sortowaniem rekordów. Oczywiście nie ma gwarancji, że
%%physloc%% będzie dostępny także w wersji RTM, ale na razie wszystko na to wskazuje. Funkcję
sys.fn_PhysLocFormatter wywołujemy w następujący sposób:
SELECT %
%physloc%% as PhysicalLocator,
sys.fn_PhysLocFormatter(%%physloc%%) as RID
FROM test;
Powyższe zapytanie zwraca:
Dla przypomnienia: RID to numer składający się z 3 liczb całkowitych (file_id, page_id, slot_id).
Do czego można wykorzystać powyższą funkcję? Choćby do udowodnienia, że tabela tymczasowa jest serializowana na dysk. Dowód opiera się oczywiście na głęboko prawdziwym założeniu, że jeśli coś ma RID, to musi istnieć w pliku bazy danych. Poniższy skrypt tworzy tabelę tymczasową, napełnia ją jednym rekordem, a następnie zwraca RID wiersza:
CREATE TABLE #test
(
col int DEFAULT(0)
);
INSERT INTO #test DEFAULT VALUES;
SELECT sys.fn_PhysLocFormatter(%%physloc%%) FROM #test;
DROP TABLE #test;
Trzeba tylko pamiętać, że zwracana wartość, np.
(1:206:0) dotyczy bazy tempdb, nawet jeśli skrypt został wywołany w kontekście innej bazy.