@@DATEFIRST to funkcja systemowa Transact-SQL zwracająca numer bieżąco ustawionego pierwszego dnia tygodnia dla danej sesji.
Rola @@DATEFIRST w sesji Transact-SQL
@@DATEFIRST jest globalną zmienną systemową języka Transact-SQL w Microsoft SQL Server. Zwraca liczbę całkowitą określającą, który dzień tygodnia jest w bieżącej sesji traktowany jako pierwszy. Wartość nie opisuje dnia wynikającego z konkretnej daty, lecz ustawienie używane przez funkcje daty i czasu wykonujące obliczenia zależne od numeracji dni tygodnia.
Dozwolone są wartości od 1 do 7. W SQL Server liczba 1 oznacza poniedziałek, 2 wtorek, 3 środę, 4 czwartek, 5 piątek, 6 sobotę, a 7 niedzielę. Odczytanie wartości za pomocą SELECT @@DATEFIRST; pozwala sprawdzić konfigurację aktualnego połączenia. Wynik dotyczy wyłącznie sesji, w której wykonano zapytanie, dlatego dwie sesje połączone z tym samym serwerem mogą mieć różne wartości.
Ustawianie pierwszego dnia tygodnia
Zmianę ustawienia wykonuje się poleceniem SET DATEFIRST, po którym podaje się liczbę od 1 do 7, na przykład SET DATEFIRST 1; ustawia poniedziałek jako pierwszy dzień tygodnia. Następnie SELECT @@DATEFIRST; zwróci wartość 1 w tej samej sesji. Polecenie działa na poziomie połączenia, a nie jako trwała zmiana konfiguracji całej instancji SQL Server.
Początkowa wartość może zależeć od języka sesji. SQL Server przypisuje domyślne ustawienia językowe podczas nawiązywania połączenia, a polecenia takie jak SET LANGUAGE mogą wpływać na sposób interpretacji nazw i ustawień związanych z datami. Z tego powodu procedura, skrypt lub raport nie powinny zakładać wartości bez jej jawnego ustawienia, jeżeli wynik ma być identyczny niezależnie od konfiguracji połączenia.
Ustawienie pozostaje aktywne do końca sesji albo do chwili wykonania kolejnego polecenia SET DATEFIRST. Nie jest zapisywane w tabelach i nie zmienia samych wartości typu date, datetime ani datetime2. Wpływa jedynie na interpretację operacji, dla których SQL Server musi przypisać dacie numer dnia tygodnia.
Wpływ @@DATEFIRST na DATEPART i obliczenia kalendarzowe
Najważniejsze znaczenie ma zależność funkcji DATEPART od ustawienia pierwszego dnia tygodnia. Dla części weekday, oznaczanej również skrótami dw i w, SQL Server zwraca numer dnia zgodny z bieżącą wartością @@DATEFIRST. Ta sama data może więc otrzymać inny numer w dwóch sesjach, jeżeli sesje mają różne ustawienia. Sam dzień kalendarzowy pozostaje oczywiście taki sam; zmienia się wyłącznie jego numer w przyjętej numeracji tygodnia.
Przykładowo, przy SET DATEFIRST 1 poniedziałek jest dniem numer 1, a niedziela dniem numer 7. Przy SET DATEFIRST 7 niedziela otrzymuje numer 1, natomiast poniedziałek numer 2. Ma to znaczenie dla filtrów wybierających dni robocze, grupowania sprzedaży według dnia tygodnia, wyznaczania początku tygodnia oraz raportów, w których numer dnia jest zapisywany lub porównywany z inną wartością.
Nie wszystkie funkcje daty reagują na @@DATEFIRST w taki sam sposób. W szczególności dokumentacja SQL Server wskazuje, że DATEDIFF używa niedzieli jako punktu odniesienia dla zapewnienia deterministycznego działania i nie jest zmieniany przez SET DATEFIRST. Dlatego zastąpienie jednego wyrażenia innym, pozornie równoważnym, może prowadzić do różnych wyników. Przy projektowaniu obliczeń tygodniowych trzeba rozdzielić operacje zależne od numeracji dnia od operacji mierzących różnicę między datami.
Kontrola ustawienia w procedurach i raportach SQL Server
W kodzie wykonywanym w SQL Server warto traktować @@DATEFIRST jako część kontekstu wykonania. Procedura składowana, funkcja, zadanie harmonogramu albo raport może zostać uruchomiony przez różne konta, narzędzia i pule połączeń. Jeżeli ustawienie nie jest jawnie kontrolowane, ten sam tekst zapytania może zwrócić inną numerację dni tygodnia zależnie od języka lub konfiguracji sesji.
Praktyczna diagnostyka polega na zapisaniu informacji o kontekście przed analizą wyniku: wartości @@DATEFIRST, bieżącego języka sesji oraz użytego wyrażenia datowego. Pomaga to odróżnić błąd danych od błędu założeń w zapytaniu. Szczególną uwagę należy zwrócić na kod, który porównuje DATEPART(weekday, data) z liczbami zapisanymi na stałe. Taki warunek jest jednoznaczny dopiero wtedy, gdy wcześniej ustalono numerację obowiązującą w danym połączeniu.
Podczas diagnostyki problemów z raportami lub aplikacją korzystającą z SQL Server należy sprawdzić, czy ustawienie nie jest zmieniane w trakcie obsługi połączenia. Dotyczy to także puli połączeń, w której sesja może zostać ponownie użyta przez inną operację. W razie niezgodności wyników analizuje się tekst zapytania, procedury ustawiające DATEFIRST, sposób tworzenia połączeń oraz wartości wejściowe dat. Naprawa polega zwykle na ujednoliceniu kontekstu sesji i zastąpieniu niejawnych założeń obliczeniami jasno określającymi oczekiwaną numerację tygodnia.