DATEADD (Transact-SQL)

Gibt einen angegebenen date-Wert zurück, wobei das angegebene number-Intervall (ganze Zahl mit Vorzeichen) einem angegebenen datepart-Wert für diesen date-Wert hinzugefügt wird.

Eine Übersicht über alle Datums- und Uhrzeitdatentypen und zugehörigen Funktionen von Transact-SQL finden Sie unter Datums- und Uhrzeitdatentypen und zugehörige Funktionen (Transact-SQL). Informationen und Beispiele, die für alle Datums- und Uhrzeitdatentypen und zugehörige Funktionen gelten, finden Sie unter Verwenden von Datums- und Zeitdaten.

Themenlink (Symbol)Transact-SQL-Syntaxkonventionen

Syntax

DATEADD (datepart , number, date )

Argumente

  • datepart
    Der Teil von date, dem ein integernumber hinzugefügt wird. In der folgenden Tabelle sind alle gültigen datepart-Argumente aufgeführt. Benutzerdefinierte Variablenentsprechungen sind nicht gültig.

    datepart

    Abkürzungen

    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
    Ein Ausdruck, der in einen int-Wert aufgelöst werden kann, der einem datepart-Wert von date hinzugefügt wird. Benutzerdefinierte Variablen sind gültig.

    Wenn Sie einen Wert mit einem Dezimalbruch angeben, wird der Bruch abgeschnitten und nicht gerundet.

  • date
    Ein Ausdruck, der in einen time-Wert, einen date-Wert, einen smalldatetime-Wert, einen datetime-Wert, einen datetime2-Wert oder einen datetimeoffset-Wert aufgelöst werden kann. Bei date kann es sich um einen Ausdruck, einen Spaltenausdruck, eine benutzerdefinierte Variable oder ein Zeichenfolgenliteral handeln. Wenn der Ausdruck ein Zeichenfolgenliteral ist, muss er in datetime aufgelöst werden. Verwenden Sie vierstellige Jahreszahlen, um Mehrdeutigkeit zu vermeiden. Informationen zu zweistelligen Jahreszahlen finden Sie unter two digit year cutoff (Option).

Rückgabetypen

Beim Rückgabedatentyp handelt es sich um den Datentyp des date-Arguments. Eine Ausnahme bilden hier Zeichenfolgenliterale.

Der Rückgabedatentyp für ein Zeichenfolgenliteral ist datetime. Wenn die Dezimalstellen für die Sekunden des Zeichenfolgenliterals mehr als drei Positionen (.nnn) umfassen oder einen Zeitzonenoffset-Teil enthalten, wird ein Fehler ausgelöst.

HinweisHinweis

Wenn Zeichenfolgenliterale nicht explizit für den date-Parameter umgewandelt werden, erhalten Lokale mit dem Datumsformat Tag-Monat-Jahr (TMJ) möglicherweise falsche Ergebnisse, wenn DATEADD in Verbindung mit anderen Datum/Uhrzeit-Funktionen verwendet wird.

Rückgabe eines datetime2-Typs

DATEADD gibt einen datetime2-Typ zurück, wenn es sich beim date-Parameter um einen datetime2-Typ handelt. Bei Verwendung von Zeichenfolgenliteralen für den date-Parameter müssen diese explizit in einen datetime2-Typ umgewandelt werden, damit DATEADD einen datetime2-Typ zurückgibt.

Rückgabewert

datepart-Argument

dayofyear, day und weekday geben den gleichen Wert zurück.

Jedes datepart-Argument und die zugehörigen Abkürzungen geben den gleichen Wert zurück.

Wenn datepart den Wert month aufweist und der für date angegebene Monat mehr Tage umfasst als der Rückgabemonat und der für date angegebene Tag nicht im Rückgabemonat vorhanden ist, wird der letzte Tag des Rückgabemonats zurückgegeben. Beispiel: Der September hat 30 Tage. Daher geben die beiden folgenden Anweisungen 2006-09-30 00:00:00.000 zurück:

SELECT DATEADD(month, 1, '2006-08-30')

SELECT DATEADD(month, 1, '2006-08-31')

number-Argument

Das number-Argument kann den Bereich von int nicht überschreiten. In den folgenden Anweisungen überschreitet das Argument für number den Bereich von int um 1. Die folgende Fehlermeldung wird zurückgegeben: "Arithmetischer Überlauffehler beim Konvertieren des Ausdrucks in den int-Datentyp."

SELECT DATEADD(year,2147483648, '2006-07-31');
SELECT DATEADD(year,-2147483649, '2006-07-31');

date-Argument

Das date-Argument kann nicht zu einem Wert außerhalb des Bereichs seines Datentyps inkrementiert werden. In den folgenden Anweisungen überschreitet der number-Wert, der dem date-Wert hinzugefügt wird, den Bereich des date-Datentyps. Die folgende Fehlermeldung wird zurückgegeben: "Überlauf beim Hinzufügen eines Werts zu einer 'datetime'-Spalte."

SELECT DATEADD(year,2147483647, '2006-07-31');
SELECT DATEADD(year,-2147483647, '2006-07-31');

Rückgabewerte für ein Datum vom Typ smalldatetime und einen datepart-Wert in Sekunden oder Sekundenbruchteilen

Die Sekundenangabe eines smalldatetime-Werts ist immer 00. Wenn date den Wert smalldatetime hat, gilt Folgendes:

  • Wenn datepart den Wert second hat und number zwischen -30 und +29 liegt, findet keine Addition statt.

  • Wenn datepart den Wert second hat und number unter -30 oder über +29 liegt, findet eine bei einer Minute beginnende Addition statt.

  • Wenn datepart den Wert millisecond hat und number zwischen -30001 und +29998 liegt, findet keine Addition statt.

  • Wenn datepart den Wert millisecond hat und number unter -30001 oder über +29998 liegt, findet eine bei einer Minute beginnende Addition statt.

Hinweise

DATEADD kann in den Klauseln SELECT <Liste>, WHERE, HAVING, GROUP BY und ORDER BY verwendet werden.

Genauigkeit in Sekundenbruchteilen

Für einen datepart-Wert microsecond oder nanosecond für die date-Datentypen smalldatetime, date und datetime ist Addition nicht zulässig.

Millisekunden besitzen drei Dezimalstellen (.123). Mikrosekunden besitzen sechs Dezimalstellen (.123456). Nanosekunden besitzen neun Dezimalstellen (.123456789). Die Datentypen time, datetime2 und datetimeoffset besitzen maximal sieben Dezimalstellen (.1234567). Wenn datepart den Wert nanosecond hat, muss number 100 sein, bevor die Sekundenbruchteile von date erhöht werden. Hat number einen Wert zwischen 1 und 49, wird er auf 0 abgerundet. Eine Zahl zwischen 50 und 99 wird auf 100 aufgerundet.

Durch die folgenden Anweisungen wird datepart mit millisecond, microsecond oder nanosecond hinzugefügt.

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
*/

Zeitzonenoffset

Für einen Zeitzonenoffset ist Addition nicht zulässig.

Beispiele

A. Inkrementieren von datepart mit einem Intervall von 1

Jede der folgenden Anweisungen inkrementiert datepart mit einem Intervall von 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. Inkrementieren mehrerer Ebenen von datepart in einer Anweisung

Jede der folgenden Anweisungen inkrementiert datepart um einen number-Wert, der hoch genug ist, um auch den nächsthöheren datepart-Wert von date zu inkrementieren.

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. Verwenden von Ausdrücken als Argumente für den number-Parameter und den date-Parameter

In den folgenden Beispielen werden verschiedene Typen von Ausdrücken als Argumente für den number-Parameter und den date-Parameter verwendet.

Angeben einer Spalte als Argument für date

Im folgenden Beispiel werden 2 Tage zu jedem OrderDate hinzugefügt, um einen neuen PromisedShipDate-Wert zu berechnen.

USE AdventureWorks;
GO
SELECT SalesOrderID
    ,OrderDate 
    ,DATEADD(day,2,OrderDate) AS PromisedShipDate
FROM Sales.SalesOrderHeader;

Angeben von benutzerdefinierten Variablen als Argumente für number und date

Im folgenden Beispiel werden benutzerdefinierte Variablen als Argumente für number und date angegeben.

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);

Angeben einer skalaren Systemfunktion als Argument für date

Im folgenden Beispiel wird SYSDATETIME für date angegeben.

SELECT DATEADD(month, 1, SYSDATETIME());

Angeben von skalaren Unterabfragen und skalaren Funktionen als Argumente für number und date

Im folgenden Beispiel werden skalare Unterabfragen und skalare Funktionen (MAX(ModifiedDate)) als Argumente für number und date verwendet. (SELECT TOP 1 ContactID FROM Person.Contact) ist ein Beispielargument für den number-Parameter, das veranschaulichen soll, wie ein number-Argument aus einer Werteliste ausgewählt wird.

USE AdventureWorks;
GO
SELECT DATEADD(month,(SELECT TOP 1 ContactID FROM Person.Contact),
    (SELECT MAX(ModifiedDate) FROM Person.Contact));

Angeben von Konstanten als Argumente für number und date

Im folgenden Beispiel werden numerische Konstanten und Zeichenkonstanten als Argumente für number und date verwendet.

SELECT DATEADD(minute, 1, '2007-05-07 09:53:01.0376635');

Angeben von numerischen Ausdrücken und skalaren Systemfunktionen als Argumente für number und date

Im folgenden Beispiel werden numerische Ausdrücke (-(10/2)), unäre Operatoren (-), ein arithmetischer Operator (/) und skalare Systemfunktionen (SYSDATETIME) als Argumente für number und date verwendet.

SELECT DATEADD(month,-(10/2), SYSDATETIME());

Angeben von Rangfolgefunktionen als Argumente für number

Im folgenden Beispiel wird eine Rangfolgefunktion als Argument für number verwendet.

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;

Angeben einer Aggregatfensterfunktion als Argument für number

Im folgenden Beispiel wird eine Aggregatfensterfunktion als Argument für number verwendet.

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. Verwenden von DATEADD für Lokale mit dem Datumsformat TMJ

In den folgenden Beispielen wird gezeigt, wie Zeichenfolgenliterale mit DATEADD für bestimmte Lokale verwendet werden.

Demonstration der Tücken bei der Verwendung einer impliziten Umwandlung eines Zeichenfolgenliterals

Im folgenden Beispiel wird gezeigt, was geschieht, wenn ein Zeichenfolgenliteral nicht explizit umgewandelt wird.

SET LANGUAGE Español;

GO

SELECT DATENAME(m, DATEADD(d, 0,'1987-03-07'));

SELECT DATENAME(m, '1987-03-07');

GO

Die erste SELECT-Anweisung gibt julio (Juli) für den Monat zurück, und die zweite SELECT-Anweisung gibt marzo (März) für den Monat zurück.

Vermeiden von falschen Ergebnissen durch die explizite Umwandlung des Zeichenfolgenliterals

Im folgenden Beispiel wird gezeigt, wie der date-Parameter explizit umgewandelt werden, damit falsche Ergebnisse vermieden werden.

SET LANGUAGE Español;

GO

SELECT DATENAME(m, DATEADD(d, 0, CAST('1987-03-07' AS datetime2)));

SELECT DATENAME(m, '1987-03-07');

GO

Beide SELECT-Anweisungen geben marzo (März) für den Monat zurück.

Verwenden einer datetime2-Variablen anstelle eines Zeichenfolgenliterals

Im folgenden Beispiel wird die direkte Verwendung eines Zeichenfolgenliterals vermieden.

SET LANGUAGE Español;

GO

DECLARE @d datetime2 = '1987-03-07';

SELECT DATENAME(m, DATEADD(d, 0, @d));

SELECT DATENAME(m, @d);

GO

Siehe auch

Verweis