J'exécute SQL Server 2008 sur une machine avec des paramètres régionaux dont le lundi est le premier jour de la semaine. Si je crée une colonne calculée dans une table pour calculer le jour de la semaine pour un champ de date, je reçois 2 pour une date de lundi au lieu de 1.
Existe-t-il une propriété pour la table, la base de données ou le serveur que je dois définir?
Le premier jour de la semaine est basé sur les paramètres de langue du serveur. Le paramètre par défaut pour us_english est 7 (dimanche).
Vous pouvez trouver le premier jour de la semaine en cours à l’aide de SELECT @@DATEFIRST
Cependant, vous pouvez utiliser DATEFIRST
pour cela. Il suffit de le mettre en haut de votre requête
SET DATEFIRST 1;
définit le lundi sur le premier jour de la semaine pour la connexion en cours.
Juste mis en requête
SET DATEFIRST 1;
Valeur Le premier jour de la semaine est 1 lundi 2 mardi 3 mercredi 4 jeudi 5 vendredi 6 samedi 7 (par défaut, anglais américain) dimanche
Une situation horrible .... Supposons que vous utilisez un serveur partagé et que les applications peuvent être déplacées vers différents serveurs en fonction de leur charge. Pour une raison quelconque, un serveur a été configuré avec une première date différente pour une autre application .... et vous renvoyez le jour de la semaine dans une fonction de table (c.-à-d. impossible de définir la première date dans cette fonction). Cela garantira toujours le lundi comme premier jour.
CREATE FUNCTION fnGetMondayWD(@WD INT)
RETURNS INT
AS
BEGIN
/* think of 1 to 7 as a clock that can rotate forwards or backwards */
DECLARE @OFFSET INT, @calc INT;
SET @offset = @@DATEFIRST + @WD - 1;--Monday DateFirst
SET @calc = IIF(@offset > 7, @offset - 7, @offset); -- could be @offset % 7 (less readable more efficient)
RETURN @calc;
END;
go
-- Test Cases
SET datefirst 7
select dbo.fnGetMondayWD(2) Mon,
dbo.fnGetMondayWD(3)Tue,
dbo.fnGetMondayWD(4)Wed,
dbo.fnGetMondayWD(5)Thur,
dbo.fnGetMondayWD(6)Fri,
dbo.fnGetMondayWD(7)Sat,
dbo.fnGetMondayWD(1)Sun
SET datefirst 6
select dbo.fnGetMondayWD(3) Mon,
dbo.fnGetMondayWD(4)Tue,
dbo.fnGetMondayWD(5)Wed,
dbo.fnGetMondayWD(6)Thur,
dbo.fnGetMondayWD(7)Fri,
dbo.fnGetMondayWD(1)Sat,
dbo.fnGetMondayWD(2)Sun
SET datefirst 5
select dbo.fnGetMondayWD(4) Mon,
dbo.fnGetMondayWD(5)Tue,
dbo.fnGetMondayWD(6)Wed,
dbo.fnGetMondayWD(7)Thur,
dbo.fnGetMondayWD(1)Fri,
dbo.fnGetMondayWD(2)Sat,
dbo.fnGetMondayWD(3)Sun
SET datefirst 1
select dbo.fnGetMondayWD(1) Mon,
dbo.fnGetMondayWD(2)Tue,
dbo.fnGetMondayWD(3)Wed,
dbo.fnGetMondayWD(4)Thur,
dbo.fnGetMondayWD(5)Fri,
dbo.fnGetMondayWD(6)Sat,
dbo.fnGetMondayWD(7)Sun
Vous pouvez utiliser DATEPART(dw, GETDATE())
mais sachez que le résultat dépendra du paramètre SQL Server @@DATEFIRST
qui correspond au premier jour de la semaine (la valeur par défaut 7 pour l'Europe est dimanche).
Une autre méthode consiste à spécifier explicitement la valeur du premier jour de la semaine en tant que paramètre et à éviter de dépendre du paramètre @@DATEFIRST
. Vous pouvez utiliser la formule suivante pour y parvenir lorsque vous en avez besoin:
(DATEPART(dw, GETDATE()) + @@DATEFIRST + 6 - @WeekStartDay) % 7 + 1
où @WeekStartDay
est le premier jour de la semaine que vous souhaitez pour votre système (de 1 à 7, du lundi au dimanche).
Je l'ai emballé dans la fonction ci-dessous afin que nous puissions le réutiliser facilement:
CREATE FUNCTION [dbo].[GetDayInWeek](@InputDateTime DATETIME, @WeekStartDay INT)
RETURNS INT
AS
BEGIN
--Note: @WeekStartDay is number from [1 - 7] which is from Monday to Sunday
RETURN (DATEPART(dw, @InputDateTime) + @@DATEFIRST + 6 - @WeekStartDay) % 7 + 1
END
Exemple d'utilisation: GetDayInWeek('2019-02-04 00:00:00', 1)
Cela équivaut à suivre (mais indépendamment du paramètre DATEFIRST):
SET DATEFIRST 1
DATEPART(dw, '2019-02-04 00:00:00')