DATEADD (Transact-SQL)
Retourne une date spécifiée avec l'intervalle number indiqué (entier signé) ajouté à une datepart spécifiée de cette date.
Pour obtenir une vue d'ensemble de tous les types de données et fonctions de date et d'heure Transact-SQL, consultez Types de données et fonctions de date et d'heure (Transact-SQL). Pour obtenir des informations et des exemples communs aux types de données et fonctions de date et d'heure, consultez Utilisation des données de date et d'heure.
Syntaxe
DATEADD (datepart , number, date )
Arguments
datepart
Partie de date à laquelle un integernumber est ajouté. Le tableau suivant répertorie tous les arguments datepart valides. Les équivalents de variables définis par l'utilisateur ne sont pas valides.datepart
Abréviations
year
yy, yyyy
quarter
qq, q
month
mm, m
dayofyear
dy, y
day
dd, d
week
wk, ww
weekday
dw, w
hour
hh
minute
mi, n
second
ss, s
millisecond
ms
microsecond
mcs
nanosecond
ns
number
Expression qui peut être résolue en une valeur int qui est ajoutée à une datepart de date. Les variables définies par l'utilisateur sont valides.Si vous spécifiez une valeur avec une fraction décimale, la fraction est tronquée et n'est pas arrondie.
date
Est une expression qui peut être résolue en une valeur time, date, smalldatetime, datetime, datetime2 ou datetimeoffset. date peut être une expression, une expression de colonne, une variable définie par l'utilisateur ou un littéral de chaîne. Si l'expression est un littéral de chaîne, elle doit être résolue en datetime. Pour éviter toute ambiguïté, représentez les années à l'aide de quatre chiffres. Pour plus d'informations sur les années à deux chiffres, consultez Option two digit year cutoff.
Types des valeurs renvoyées
Le type de données retournées est le type de données de l'argument date, à l'exception des littéraux de chaîne.
Le type de données retournées pour un littéral de chaîne est datetime. Une erreur sera déclenchée si l'échelle des secondes du littéral de chaîne comprend plus de trois positions (.nnn) ou contient la partie du décalage de fuseau horaire.
[!REMARQUE]
Si les littéraux de chaîne ne sont pas convertis explicitement pour le paramètre date, les paramètres régionaux qui utilisent un format de date jour-mois-année (jma) peuvent obtenir des résultats incorrects lorsque DATEADD est utilisé conjointement à d'autres fonctions de date/heure.
Retour d'un type datetime2
DATEADD retourne un type datetime2 lorsque le paramètre date présente un type datetime2. Lorsque vous utilisez des littéraux de chaîne pour le paramètre date, vous devez les convertir explicitement en type datetime2 pour DATEADD pour retourner un type datetime2.
Valeur de retour
Argument datepart
dayofyear, day et weekday retournent la même valeur.
Chaque datepart et ses abréviations retournent la même valeur.
Si datepart est month, si le mois date comprend plus de jours que le mois retourné et que le jour date n'existe pas dans le mois retourné, le dernier jour du mois retourné est renvoyé. Par exemple, septembre compte 30 jours ; par conséquent, les deux instructions suivantes retournent 2006-09-30 00:00:00.000:
SELECT DATEADD(month, 1, '2006-08-30')
SELECT DATEADD(month, 1, '2006-08-31')
Argument number
L'argument number ne peut pas dépasser la plage des int. Dans les instructions suivantes, l'argument pour number dépasse la plage des int de 1. Le message d'erreur suivant est retourné : « Une erreur de dépassement arithmétique s'est produite lors de la conversion de l'expression en type de données int ».
SELECT DATEADD(year,2147483648, '2006-07-31');
SELECT DATEADD(year,-2147483649, '2006-07-31');
Argument date
L'argument date ne peut pas être incrémenté à une valeur située hors de la plage de son type de données. Dans les instructions suivantes, la valeur number qui est ajoutée à la valeur date dépasse la plage du type de données date. Le message d'erreur suivant est retourné : « L'ajout d'une valeur à une colonne datetime a provoqué un dépassement de capacité ».
SELECT DATEADD(year,2147483647, '2006-07-31');
SELECT DATEADD(year,-2147483647, '2006-07-31');
Valeurs retournées pour une date smalldatetime et une partie de date seconde ou fractions de seconde
La partie secondes d'une valeur smalldatetime est toujours 00. Si date est smalldatetime, les éléments suivants s'appliquent :
Si datepart est second et number se situe entre -30 et +29, aucun ajout n'est effectué.
Si datepart est second et number est inférieur à -30 ou supérieur à +29, l'ajout est effectué en commençant à une minute.
Si datepart est millisecond et number se situe entre -30001 et +29998, aucun ajout n'est effectué.
Si datepart est millisecond et number est inférieur à -30001 ou supérieur à +29998, l'ajout est effectué en commençant à une minute.
Notes
DATEADD peut être utilisé dans les clauses SELECT <list>, WHERE, HAVING, GROUP BY et ORDER BY.
Précision en fractions de seconde
L'ajout pour un datepart de microsecond ou nanosecond pour les types de données datesmalldatetime, date et datetime n'est pas autorisé.
Les millisecondes ont une échelle de 3 (,123). Les microsecondes ont une échelle de 6 (,123456). Les nanosecondes ont une échelle de 9 (,123456789). Les types de données time, datetime2 et datetimeoffset ont une échelle maximale de 7 (,1234567). Si datepart est nanosecond, number doit être égal à 100 avant que les fractions de seconde de date n'augmentent Un number situé entre 1 et 49 est arrondi à 0 et un nombre situé entre 50 et 99 est arrondi à 100.
Les instructions suivantes ajoutent un datepart de millisecond, microsecond ou nanosecond.
DECLARE @datetime2 datetime2 = '2007-01-01 13:10:10.1111111'
SELECT '1 millisecond' ,DATEADD(millisecond,1,@datetime2)
UNION ALL
SELECT '2 milliseconds', DATEADD(millisecond,2,@datetime2)
UNION ALL
SELECT '1 microsecond', DATEADD(microsecond,1,@datetime2)
UNION ALL
SELECT '2 microseconds', DATEADD(microsecond,2,@datetime2)
UNION ALL
SELECT '49 nanoseconds', DATEADD(nanosecond,49,@datetime2)
UNION ALL
SELECT '50 nanoseconds', DATEADD(nanosecond,50,@datetime2)
UNION ALL
SELECT '150 nanoseconds', DATEADD(nanosecond,150,@datetime2);
/*
Returns:
1 millisecond 2007-01-01 13:10:10.1121111
2 milliseconds 2007-01-01 13:10:10.1131111
1 microsecond 2007-01-01 13:10:10.1111121
2 microseconds 2007-01-01 13:10:10.1111131
49 nanoseconds 2007-01-01 13:10:10.1111111
50 nanoseconds 2007-01-01 13:10:10.1111112
150 nanoseconds 2007-01-01 13:10:10.1111113
*/
Décalage de fuseau horaire
L'ajout n'est pas autorisé pour le décalage de fuseau horaire.
Exemple
A. Incrémentation d'une partie de date d'un intervalle de 1
Chacune des instructions suivantes incrémente datepart d'un intervalle de 1.
DECLARE @datetime2 datetime2 = '2007-01-01 13:10:10.1111111'
SELECT 'year', DATEADD(year,1,@datetime2)
UNION ALL
SELECT 'quarter',DATEADD(quarter,1,@datetime2)
UNION ALL
SELECT 'month',DATEADD(month,1,@datetime2)
UNION ALL
SELECT 'dayofyear',DATEADD(dayofyear,1,@datetime2)
UNION ALL
SELECT 'day',DATEADD(day,1,@datetime2)
UNION ALL
SELECT 'week',DATEADD(week,1,@datetime2)
UNION ALL
SELECT 'weekday',DATEADD(weekday,1,@datetime2)
UNION ALL
SELECT 'hour',DATEADD(hour,1,@datetime2)
UNION ALL
SELECT 'minute',DATEADD(minute,1,@datetime2)
UNION ALL
SELECT 'second',DATEADD(second,1,@datetime2)
UNION ALL
SELECT 'millisecond',DATEADD(millisecond,1,@datetime2)
UNION ALL
SELECT 'microsecond',DATEADD(microsecond,1,@datetime2)
UNION ALL
SELECT 'nanosecond',DATEADD(nanosecond,1,@datetime2);
/*
Year 2008-01-01 13:10:10.1111111
quarter 2007-04-01 13:10:10.1111111
month 2007-02-01 13:10:10.1111111
dayofyear 2007-01-02 13:10:10.1111111
day 2007-01-02 13:10:10.1111111
week 2007-01-08 13:10:10.1111111
weekday 2007-01-02 13:10:10.1111111
hour 2007-01-01 14:10:10.1111111
minute 2007-01-01 13:11:10.1111111
second 2007-01-01 13:10:11.1111111
millisecond 2007-01-01 13:10:10.1121111
microsecond 2007-01-01 13:10:10.1111121
nanosecond 2007-01-01 13:10:10.1111111
*/
B. Incrémentation de plusieurs niveaux d'une partie de date dans une instruction
Chacune des instructions suivantes incrémente datepart d'un number assez grand pour incrémenter également le datepart immédiatement supérieur de date.
DECLARE @datetime2 datetime2;
SET @datetime2 = '2007-01-01 01:01:01.1111111';
--Statement Result
-------------------------------------------------------------------
SELECT DATEADD(quarter,4,@datetime2); --2008-01-01 01:01:01.110
SELECT DATEADD(month,13,@datetime2); --2008-02-01 01:01:01.110
SELECT DATEADD(dayofyear,365,@datetime2); --2008-01-01 01:01:01.110
SELECT DATEADD(day,365,@datetime2); --2008-01-01 01:01:01.110
SELECT DATEADD(week,5,@datetime2); --2007-02-05 01:01:01.110
SELECT DATEADD(weekday,31,@datetime2); --2007-02-01 01:01:01.110
SELECT DATEADD(hour,23,@datetime2); --2007-01-02 00:01:01.110
SELECT DATEADD(minute,59,@datetime2); --2007-01-01 02:00:01.110
SELECT DATEADD(second,59,@datetime2); --2007-01-01 01:02:00.110
SELECT DATEADD(millisecond,1,@datetime2); --2007-01-01 01:01:01.110
C. Utilisation d'expressions comme arguments pour les paramètres de date et numériques
Les exemples suivants utilisent différents types d'expressions comme arguments pour les paramètres number et date.
Spécification de la colonne comme date
L'exemple suivant ajoute 2 jours à chaque OrderDate pour calculer une nouvelle PromisedShipDate.
USE AdventureWorks;
GO
SELECT SalesOrderID
,OrderDate
,DATEADD(day,2,OrderDate) AS PromisedShipDate
FROM Sales.SalesOrderHeader;
Spécification de variables définies par l'utilisateur comme nombre et date
L'exemple suivant spécifie des variables définies par l'utilisateur comme arguments pour number et date.
DECLARE @days int;
DECLARE @datetime datetime;
SET @days = 365;
SET @datetime = '2000-01-01 01:01:01.111'; /* 2000 was a leap year */
SELECT DATEADD(day, @days, @datetime);
Spécification de la fonction système scalaire comme date
L'exemple suivant spécifie SYSDATETIME pour date.
SELECT DATEADD(month, 1, SYSDATETIME());
Spécification de sous-requêtes scalaires et de fonctions scalaires comme nombre et date
L'exemple suivant utilise des sous-requêtes scalaires et des fonctions scalaires, MAX(ModifiedDate), en tant qu'arguments pour number et date. (SELECT TOP 1 ContactID FROM Person.Contact) est un argument artificiel pour le paramètre numérique afin d'illustrer la sélection d'un argument number dans une liste de valeurs.
USE AdventureWorks;
GO
SELECT DATEADD(month,(SELECT TOP 1 ContactID FROM Person.Contact),
(SELECT MAX(ModifiedDate) FROM Person.Contact));
Spécification de constantes comme nombre et date
L'exemple suivant utilise des constantes numériques et de caractère comme arguments pour number et date.
SELECT DATEADD(minute, 1, '2007-05-07 09:53:01.0376635');
Spécification d'expressions numériques et de fonctions système scalaires comme nombre et date
L'exemple suivant utilise des expressions numériques (-(10/2)), opérateurs unaires (-, un opérateur arithmétique (/) et des fonctions système scalaires (SYSDATETIME) comme arguments pour number et date.
SELECT DATEADD(month,-(10/2), SYSDATETIME());
Spécification de fonctions de classement comme nombre
L'exemple suivant utilise une fonction de classement comme arguments pour number.
USE AdventureWorks;
GO
SELECT c.FirstName, c.LastName
,DATEADD(day,ROW_NUMBER() OVER (ORDER BY
a.PostalCode),SYSDATETIME()) AS 'Row Number'
FROM Sales.SalesPerson s
INNER JOIN Person.Contact c
ON s.SalesPersonID = c.ContactID
INNER JOIN Person.Address a
ON a.AddressID = c.ContactID
WHERE TerritoryID IS NOT NULL
AND SalesYTD <> 0;
Spécification d'une fonction d'agrégation comme nombre
L'exemple suivant utilise une fonction d'agrégation comme argument pour number.
USE AdventureWorks;
GO
SELECT SalesOrderID, ProductID, OrderQty
,DATEADD(day,SUM(OrderQty)
OVER(PARTITION BY SalesOrderID),SYSDATETIME()) AS 'Total'
FROM Sales.SalesOrderDetail
WHERE SalesOrderID IN(43659,43664);
GO
D. Utilisation de DATEADD pour les paramètres régionaux qui utilisent le format de date jma
Les exemples suivants indiquent comment utiliser des littéraux de chaîne avec DATEADD pour certains paramètres régionaux.
Montrer les pièges de l'utilisation d'une conversion implicite d'un littéral de chaîne
L'exemple suivant montre ce qui arrive lorsqu'un littéral de chaîne n'est pas converti explicitement.
SET LANGUAGE Español;
GO
SELECT DATENAME(m, DATEADD(d, 0,'1987-03-07'));
SELECT DATENAME(m, '1987-03-07');
GO
La première instruction select retourne julio (juillet) pour le mois, tandis que la deuxième retourne marzo (mars) pour le mois.
Solution pour éviter des résultats erronés en convertissant le littéral de chaîne explicitement
L'exemple suivant indique comment convertir explicitement le paramètre date pour éviter les résultats erronés.
SET LANGUAGE Español;
GO
SELECT DATENAME(m, DATEADD(d, 0, CAST('1987-03-07' AS datetime2)));
SELECT DATENAME(m, '1987-03-07');
GO
Les deux instructions select retournent marzo (mars) pour le mois.
Utilisation d'une variable datetime2 à la place d'un littéral de chaîne
L'exemple suivant évite l'utilisation directe d'un littéral de chaîne.
SET LANGUAGE Español;
GO
DECLARE @d datetime2 = '1987-03-07';
SELECT DATENAME(m, DATEADD(d, 0, @d));
SELECT DATENAME(m, @d);
GO