Share via


DATEADD (Transact-SQL)

Restituisce il valore date specificato con l'intervallo di valori number specificato (interi con segno) aggiunto a un valore datepart specificato del valore date stesso.

Per una panoramica di tutti i tipi di dati e delle funzioni di data e ora Transact-SQL, vedere Funzioni e tipi di dati di data e ora (Transact-SQL).

Icona di collegamento a un argomento Convenzioni della sintassi Transact-SQL

Sintassi

DATEADD (datepart , number , date )

Argomenti

  • datepart
    Parte di date a cui viene aggiunto un valore number integer. Nella tabella seguente vengono elencati tutti gli argomenti di datepart validi. Variabili definite dall'utente equivalenti non sono valide.

    datepart

    Abbreviazioni

    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
    Espressione che può essere risolta in un tipo int aggiunto a datepart di date. Le variabili definite dall'utente sono valide.

    Se un valore viene specificato mediante una frazione decimale, la frazione viene troncata e non arrotondata.

  • date
    Espressione che può essere risolta in un valore di tipo time, date, smalldatetime, datetime, datetime2 o datetimeoffset. date può essere costituito da un'espressione, da un'espressione di colonna, da una variabile definita dall'utente o da un valore letterale stringa. Se l'espressione è un valore letterale stringa, deve essere risolta in un tipo datetime. Per evitare ambiguità, esprimere gli anni nel formato a quattro cifre. Per informazioni sul formato dell'anno a due cifre, vedere Configurare l'opzione di configurazione del server two-digit year cutoff.

Tipi restituiti

Il tipo di dati restituito è rappresentato dal tipo di dati dell'argomento date, ad eccezione dei valori letterali stringa.

Il tipo di dati restituito per un valore letterale stringa è datetime. Se la scala dei secondi del valore letterale stringa ha più di tre posizioni ( nnn) o contiene la parte relativa alla differenza di fuso orario, viene generato un errore.

Argomento datepart

dayofyear, day e weekday restituiscono lo stesso valore.

Ogni valore datepart e le relative abbreviazioni restituiscono lo stesso valore.

Se datepart è month, il mese del valore date ha più giorni del mese restituito e il giorno del valore date non esiste nel mese restituito, viene restituito l'ultimo giorno del mese restituito. Ad esempio, settembre ha 30 giorni. Pertanto, le due istruzioni seguenti restituiscono 2006-09-30 00:00:00.000:

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

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

Un argomento number non può superare l'intervallo del tipo int. Nelle istruzioni seguenti, l'argomento per il parametro number supera l'intervallo di int di una unità. Viene restituito il messaggio di errore seguente: "Msg 8115, Level 16, State 2, Line 1. Arithmetic overflow error converting expression to data type int."

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

Non è possibile incrementare un argomento per il parametro date a un valore al di fuori dell'intervallo consentito per il tipo di dati corrispondente. Nelle istruzioni seguenti, il valore number aggiunto al valore date supera l'intervallo del tipo di dati date. Viene restituito il messaggio di errore seguente: "Msg 517, Level 16, State 1, Line 1 Adding a value to a 'datetime' column caused overflow".

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

La seconda parte di un valore smalldatetime è sempre 00. Se l'argomento date è smalldatetime, si applicano le condizioni seguenti:

  • Se datepart corrisponde a second e number è compreso tra -30 e +29, non viene eseguita alcuna aggiunta.

  • Se datepart corrisponde a second e number è minore di -30 o maggiore di +29, l'aggiunta viene eseguita iniziando da un minuto.

  • Se datepart corrisponde a millisecond e number è compreso tra -30001 e +29998, non viene eseguita alcuna aggiunta.

  • Se datepart corrisponde a millisecond e number è minore di -30001 o maggiore di +29998, l'aggiunta viene eseguita iniziando da un minuto.

Osservazioni

È possibile utilizzare DATEADD nelle clausole SELECT <list>, WHERE, HAVING, GROUP BY e ORDER BY.

Precisione in secondi frazionari

L'aggiunta a un valore datepart di microsecond o nanosecond per i tipi di dati date smalldatetime, date e datetime non è consentita.

I millisecondi hanno una scala di 3 (.123), i microsecondi hanno una scala di 6 (.123456) e i nanosecondi hanno una scala di 9 (.123456789). I tipi di dati time, datetime2e datetimeoffset hanno una scala massima di 7 (.1234567). Se un valore datepart è costituito da nanosecond, number deve essere pari a 100 perché si verifichi l'aumento dei secondi frazionari di date. Un number tra 1 e 49 viene arrotondato per difetto a 0 e un number da 50 a 99 viene arrotondato per eccesso a 100.

Le istruzioni seguenti consentono di aggiungere un valore datepart costituito da millisecond, microsecond o 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);

Set di risultati:

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

Differenza di fuso orario

L'aggiunta non è consentita per la differenza di fuso orario.

Esempi

A.Incremento di un datepart a intervalli di una unità

Ognuna delle istruzioni seguenti incrementa il valore datepart a intervalli di una unità.

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

Set di risultati:

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.Incremento di più livelli di datepart in un'unica istruzione

Ognuna delle istruzioni seguenti incrementa datepart di un valore number abbastanza grande da incrementare anche l'argomento datepart di livello immediatamente più alto di 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.Utilizzo di espressioni come argomenti per i parametri number e date

Negli esempi seguenti sono utilizzati tipi diversi di espressioni come argomenti per i parametri number e date.

Indicazione di una colonna come data

Nell'esempio seguente vengono aggiunti 2 giorni a ogni valore nella colonna OrderDate per derivare una nuova colonna denominata PromisedShipDate.

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

Set di risultati parziale:

SalesOrderID OrderDate               PromisedShipDate
------------ ----------------------- -----------------------
43659        2005-07-01 00:00:00.000 2005-07-03 00:00:00.000
43660        2005-07-01 00:00:00.000 2005-07-03 00:00:00.000
43661        2005-07-01 00:00:00.000 2005-07-03 00:00:00.000
...
43702        2005-07-02 00:00:00.000 2005-07-04 00:00:00.000
43703        2005-07-02 00:00:00.000 2005-07-04 00:00:00.000
43704        2005-07-02 00:00:00.000 2005-07-04 00:00:00.000
43705        2005-07-02 00:00:00.000 2005-07-04 00:00:00.000
43706        2005-07-03 00:00:00.000 2005-07-05 00:00:00.000
...
43711        2005-07-04 00:00:00.000 2005-07-06 00:00:00.000
43712        2005-07-04 00:00:00.000 2005-07-06 00:00:00.000
...
43740        2005-07-11 00:00:00.000 2005-07-13 00:00:00.000
43741        2005-07-12 00:00:00.000 2005-07-14 00:00:00.000

Indicazione di variabili definite dall'utente come argomenti number e date

Nell'esempio seguente vengono specificate variabili definite dall'utente come argomenti per i parametri number e date.

DECLARE @days int = 365, 
        @datetime datetime = '2000-01-01 01:01:01.111'; /* 2000 was a leap year */;
SELECT DATEADD(day, @days, @datetime);

Set di risultati:

-----------------------
2000-12-31 01:01:01.110

(1 row(s) affected)

Indicazione di una funzione di sistema scalare come valore date

Nell'esempio seguente viene specificata la funzione SYSDATETIME per un valore date.

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

Set di risultati:

---------------------------
2013-02-06 14:29:59.6727944

(1 row(s) affected)

Indicazione di sottoquery scalari e funzioni scalari come valori number e date

Nell'esempio seguente vengono utilizzate sottoquery scalari MAX(ModifiedDate), come argomenti per number e date. (SELECT TOP 1 BusinessEntityID FROM Person.Person) è un argomento fittizio affinché il parametro number mostri come selezionare un argomento number da un elenco di valori.

USE AdventureWorks2012;
GO
SELECT DATEADD(month,(SELECT TOP 1 BusinessEntityID FROM Person.Person),
    (SELECT MAX(ModifiedDate) FROM Person.Person));

Indicazione di espressioni numeriche e funzioni di sistema scalari come valori number e date

Nell'esempio seguente viene utilizzata un'espressione numerica (-(10/2)), operatori unari (-), un operatore aritmetico (/) e funzioni di sistema scalari (SYSDATETIME) come argomenti number e date.

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

Indicazione di funzioni di rango come argomenti number

Nell'esempio seguente è utilizzata una funzione di rango come argomento number.

USE AdventureWorks2012;
GO
SELECT p.FirstName, p.LastName
    ,DATEADD(day,ROW_NUMBER() OVER (ORDER BY
        a.PostalCode),SYSDATETIME()) AS 'Row Number'
FROM Sales.SalesPerson AS s 
    INNER JOIN Person.Person AS p 
        ON s.BusinessEntityID = p.BusinessEntityID
    INNER JOIN Person.Address AS a 
        ON a.AddressID = p.BusinessEntityID
WHERE TerritoryID IS NOT NULL 
    AND SalesYTD <> 0;

Indicazione di una funzione finestra di aggregazione come argomento number

Nell'esempio seguente è utilizzata una funzione finestra di aggregazione come argomento per un parametro number.

USE AdventureWorks2012;
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

Vedere anche

Riferimento

CAST e CONVERT (Transact-SQL)