Polecenie ALTER TABLE SET (SYSTEM_VERSIONING = ON) włącza automatyczne śledzenie historii zmian danych w tabeli czasowej.
Włączenie wersjonowania systemowego w SQL Server
ALTER TABLE ... SET (SYSTEM_VERSIONING = ON) jest opcją języka Transact-SQL używaną w Microsoft SQL Server do uruchomienia wersjonowania systemowego dla tabeli czasowej. Mechanizm ten zapisuje poprzednie wersje wierszy w tabeli historii, gdy dane w tabeli głównej są aktualizowane albo usuwane. Wiersz bieżący pozostaje w tabeli podstawowej, natomiast jego wcześniejszy stan otrzymuje przedział ważności określony przez kolumny okresu systemowego. Dzięki temu możliwe jest odtworzenie stanu danych z określonego momentu, bez ręcznego tworzenia wyzwalaczy i tabel archiwalnych.
Włączenie opcji nie jest operacją niezależną od struktury tabeli. Tabela musi mieć zdefiniowane dwie kolumny typu datetime2, oznaczone jako początek i koniec okresu systemowego, oraz definicję PERIOD FOR SYSTEM_TIME. Jeżeli historia ma być przechowywana w osobnej tabeli, należy wskazać ją przez HISTORY_TABLE. Przykładowa forma polecenia może wyglądać następująco: ALTER TABLE dbo.Zamowienia SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.ZamowieniaHistoria, DATA_CONSISTENCY_CHECK = ON));. Konkretna nazwa tabeli historii musi odpowiadać rzeczywistemu schematowi i istniejącym uprawnieniom.
Warunki zgodności tabeli bieżącej i tabeli historii
SQL Server sprawdza, czy tabela główna i wskazana tabela historii mogą współpracować w ramach wersjonowania. Tabela historii powinna mieć zgodny układ kolumn: tę samą liczbę kolumn, odpowiadające sobie typy danych oraz zgodność właściwości wymaganych przez mechanizm temporalny. Kolumny okresu są przechowywane również w historii, ponieważ opisują granice obowiązywania konkretnej wersji wiersza. Tabela historii nie powinna zawierać klucza głównego ani ograniczeń, które uniemożliwiałyby dopisywanie kolejnych wersji przez SQL Server. Zwykle stosuje się w niej indeks skonfigurowany pod zapytania zakresowe dotyczące czasu.
Opcja DATA_CONSISTENCY_CHECK = ON powoduje wykonanie kontroli nakładania się przedziałów czasu pomiędzy tabelą bieżącą a historią. Dla pojedynczego klucza logicznego wersje nie powinny tworzyć sprzecznych przedziałów obowiązywania. Błędy struktury, niezgodne typy kolumn, nieprawidłowa definicja okresu albo niespójne dane w tabeli historii mogą spowodować odrzucenie polecenia. Z tego powodu przed zmianą ustawienia należy sprawdzić definicję tabeli, właściwości kolumn, indeksy, ograniczenia oraz uprawnienia do obu obiektów. Samo pomyślne wykonanie polecenia nie zastępuje oceny, czy model historii odpowiada wymaganiom aplikacji.
Jak SQL Server zapisuje kolejne wersje wierszy
Po włączeniu systemowego wersjonowania SQL Server automatycznie obsługuje przejścia wierszy pomiędzy tabelą bieżącą a tabelą historii. Przy aktualizacji istniejącego wiersza poprzednie wartości są zapisywane w historii, a w tabeli podstawowej pozostaje nowa wersja. Przy usunięciu wiersz nie znika bez śladu z całego modelu temporalnego, ponieważ jego ostatnia wersja trafia do tabeli historii. Wartości kolumn okresu są ustalane przez silnik na podstawie czasu transakcji. W praktyce granice czasowe opisują moment obowiązywania wersji w ramach przetwarzania transakcji, a nie dowolną datę biznesową wpisaną ręcznie przez użytkownika.
Zapytania dotyczące tabeli temporalnej mogą korzystać z klauzuli FOR SYSTEM_TIME, na przykład AS OF do odczytu stanu z określonego czasu, FROM ... TO do pobrania wersji w przedziale oraz ALL do połączenia danych bieżących i historycznych. Jest to istotne rozróżnienie: wersjonowanie systemowe odpowiada na pytanie, jakie wartości były zapisane w tabeli w danym czasie, ale nie definiuje automatycznie przyczyny zmiany, osoby biznesowo odpowiedzialnej za operację ani znaczenia zmienionej wartości. Jeżeli aplikacja potrzebuje takich informacji, muszą one wynikać z osobnego modelu danych i jawnie zapisanych metadanych.
Wersjonowanie zwiększa ilość przechowywanych danych, ponieważ każda zmiana może utworzyć dodatkowy rekord w tabeli historii. Należy więc uwzględnić wzrost rozmiaru bazy, indeksowanie zapytań temporalnych, kopie zapasowe oraz zasady retencji. SQL Server udostępnia ustawienia związane z przechowywaniem historii, ale ich użycie wymaga świadomego dopasowania do wersji silnika, konfiguracji bazy i wymagań aplikacji. Tabela historii nie powinna być traktowana jak zwykła tabela archiwalna, ponieważ jej rekordy są częścią mechanizmu temporalnego i muszą zachować spójność z tabelą podstawową.
Diagnostyka błędów przy zmianie ustawienia temporalnego
Jeżeli polecenie włączenia SYSTEM_VERSIONING kończy się błędem, pierwszym krokiem jest odczytanie pełnego komunikatu SQL Server, a następnie porównanie metadanych obu tabel. Szczególnej kontroli wymagają typy i kolejność kolumn, obecność kolumn początku oraz końca okresu, definicja PERIOD FOR SYSTEM_TIME, nazwa schematu tabeli historii i istniejące ograniczenia. Należy również zweryfikować, czy obiekty znajdują się w tej samej bazie danych oraz czy konto wykonujące zmianę ma wymagane uprawnienia do modyfikowania tabel.
W środowisku diagnostycznym warto sprawdzić definicje obiektów w katalogu systemowym, między innymi przez widoki sys.tables, sys.columns i sys.periods. Pomocne jest także porównanie indeksów oraz ograniczeń zapisanych w widokach katalogowych. Jeżeli problem dotyczy danych już obecnych w historii, sama korekta składni nie wystarczy: trzeba ustalić, które przedziały czasu są sprzeczne i czy ich uporządkowanie jest dopuszczalne dla aplikacji. Operacje naprawcze powinny być wykonywane po zabezpieczeniu bazy i z uwzględnieniem transakcji, blokad oraz wpływu na działające procesy.
W przypadku tabel używanych przez aplikację analiza powinna obejmować również zapytania odczytujące historię, procedury modyfikujące dane oraz raporty korzystające z kolumn okresu. Nieprawidłowe założenie, że tabela historii zawiera wyłącznie ostatnią poprzednią wartość, może prowadzić do błędnych wyników, ponieważ jeden wiersz logiczny może mieć wiele wersji. Samo polecenie ALTER TABLE zmienia konfigurację mechanizmu w SQL Server; nie naprawia automatycznie błędów modelu danych, niewłaściwych zapytań ani problemów z wydajnością. Ocena powinna dlatego łączyć komunikat błędu z definicją obiektów i rzeczywistym przepływem zmian w bazie.