SEQUENCE to obiekt SQL Server generujący kolejne wartości liczbowe niezależnie od konkretnej tabeli.
Czym jest SEQUENCE w SQL Server
SEQUENCE w Microsoft SQL Server jest obiektem bazy danych, który generuje kolejne wartości liczbowe niezależnie od konkretnej tabeli. Obiekt należy do określonego schematu, ma własny typ danych oraz zdefiniowane wartości początkowe, minimalne i maksymalne. W odróżnieniu od właściwości IDENTITY sekwencja nie jest przypisana do jednej kolumny ani jednej tabeli. Jej wartości można pobierać w wielu instrukcjach, tabelach i procedurach, o ile użytkownik ma odpowiednie uprawnienia.
Sekwencję tworzy się poleceniem CREATE SEQUENCE, na przykład z określeniem typu int lub bigint, wartości początkowej oraz przyrostu. Klauzula START WITH wskazuje pierwszą wartość, a INCREMENT BY określa zmianę przy każdym pobraniu kolejnej wartości. Domyślnym typem danych sekwencji jest bigint, jeżeli typ nie zostanie podany jawnie. Można także zdefiniować MINVALUE, MAXVALUE, zachowanie po osiągnięciu granicy przez CYCLE lub NO CYCLE, a także sposób buforowania wartości.
Pobieranie wartości i użycie w zapytaniach
Bieżącą wartość sekwencji pobiera się w SQL Server za pomocą wyrażenia NEXT VALUE FOR schema.nazwa_sekwencji. Wyrażenie może być użyte między innymi w instrukcji INSERT, dzięki czemu jedna sekwencja może zasilać klucze lub numery dokumentów w kilku tabelach. Można również ustawić sekwencję jako wartość domyślną kolumny, używając ograniczenia DEFAULT z wyrażeniem NEXT VALUE FOR. W takim układzie SQL Server pobiera numer wtedy, gdy instrukcja nie dostarcza własnej wartości dla tej kolumny.
Wartość jest rezerwowana w momencie wykonania wyrażenia, a nie dopiero po zatwierdzeniu transakcji. Jeżeli transakcja zostanie wycofana, wcześniej pobrany numer nie wraca automatycznie do puli dostępnych wartości. Z tego powodu sekwencja zapewnia generowanie uporządkowanych numerów, ale nie gwarantuje ciągłej numeracji bez luk. Luki mogą również powstać po błędzie instrukcji, anulowaniu operacji albo ponownym uruchomieniu serwera, szczególnie gdy sekwencja korzysta z pamięci podręcznej. Numer sekwencji nie powinien więc służyć jako dowód liczby zatwierdzonych rekordów.
Cache, granice zakresu i współbieżność
SQL Server może przechowywać część wartości sekwencji w pamięci, aby ograniczyć koszt zapisu informacji o każdej pobranej liczbie. Zachowanie to jest kontrolowane klauzulą CACHE albo NO CACHE. Buforowanie poprawia wydajność przy częstym pobieraniu numerów, ale po awarii lub restarcie mogą wystąpić luki związane z wartościami, które znajdowały się w pamięci, lecz nie zostały jeszcze wykorzystane. Opcja NO CACHE ogranicza ten mechanizm, jednak sama w sobie nie zapewnia numeracji bez luk, ponieważ wycofanie transakcji nadal nie cofa pobranej wartości.
Jeżeli sekwencja osiągnie określoną wartość graniczną, jej zachowanie zależy od konfiguracji. Przy NO CYCLE kolejne pobranie po przekroczeniu zakresu kończy się błędem. Przy CYCLE generator rozpoczyna ponownie od wartości minimalnej albo maksymalnej, zależnie od kierunku przyrostu. Przy cyklicznej sekwencji trzeba zagwarantować, że ponownie wygenerowana liczba nie naruszy unikatowości istniejących danych. SQL Server zapewnia synchronizację pobierania wartości przy współbieżnym dostępie, ale kolejność numerów nie musi odpowiadać kolejności zatwierdzania transakcji.
Diagnostyka konfiguracji i zastosowanie w środowisku pracy
Definicję istniejącej sekwencji można sprawdzić w widoku katalogowym sys.sequences. Widok udostępnia między innymi nazwę obiektu, schemat, typ danych, wartość bieżącą, wartość początkową, przyrost, granice zakresu, informację o cykliczności oraz ustawienia pamięci podręcznej. Do zmiany konfiguracji służy polecenie ALTER SEQUENCE, natomiast DROP SEQUENCE usuwa obiekt dopiero wtedy, gdy nie jest on używany przez zależne elementy, takie jak wartości domyślne. Przy diagnozowaniu problemu należy sprawdzić także typ kolumny docelowej, ponieważ zbyt mały zakres typu może spowodować przepełnienie mimo poprawnej konfiguracji samej sekwencji.
SEQUENCE sprawdza się wtedy, gdy numerowanie ma być wspólne dla kilku tabel, gdy aplikacja potrzebuje pobierać zakres numerów z wyprzedzeniem albo gdy generator powinien być niezależny od fizycznego zapisu rekordu. SQL Server udostępnia również procedurę systemową sys.sp_sequence_get_range, która pozwala pobrać z sekwencji określony zakres wartości do dalszego wykorzystania przez aplikację. Przy awarii aplikacji niewykorzystane numery z takiego zakresu pozostają lukami, dlatego projekt tabel i indeksów powinien zakładać brak ciągłości numeracji.