Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Converti "time" in "datetime2" in SQL Server (esempi T-SQL)

Questo articolo contiene esempi di conversione di un tempo valore a un datetime2 valore in SQL Server.

Quando converti un tempo valore a datetime2 , al valore vengono aggiunte informazioni aggiuntive. Questo perché datetime2 il tipo di dati contiene informazioni sulla data e sull'ora. Il tempo il tipo di dati, d'altra parte, contiene solo informazioni sull'ora.

In particolare, la data è impostata su '1900-01-01' (a meno che non venga arrotondato per eccesso a '1900-01-02'), la componente temporale viene copiata e, secondo la documentazione Microsoft, l'offset del fuso orario è impostato su 00:00 (anche se datetime2 il tipo di dati non è a conoscenza del fuso orario e non conserva alcun offset del fuso orario).

Quando la precisione frazionaria dei secondi di datetime2(n) il valore è maggiore di time(n) value, il valore viene arrotondato per eccesso.

Esempio 1 – Conversione esplicita mediante CAST()

Ecco un esempio di conversione esplicita. In questo caso, utilizzo il CAST() funzione direttamente all'interno di SELECT dichiarazione da convertire esplicitamente da tempo a dataora2 .

DECLARE @thetime time;
SET @thetime = '23:15:59.004007';
SELECT 
  @thetime AS 'time',
  CAST(@thetime AS datetime2) AS 'datetime2';

Risultato:

+------------------+-----------------------------+
| time             | datetime2                   |
|------------------+-----------------------------|
| 23:15:59.0040070 | 1900-01-01 23:15:59.0040070 |
+------------------+-----------------------------+

Quando effettui una conversione da tempo a dataora2 , viene aggiunto un componente data e impostato su 1900-01-01 .

Tuttavia, ci sono scenari in cui la data potrebbe essere arrotondata a 1900-01-02 . Questo dipenderà dai secondi frazionari e dalla precisione che usi. Vedi sotto per un esempio di questo.

Esempio 2 – Precisione frazionaria dei secondi

È possibile ottenere risultati diversi a seconda della precisione frazionaria di secondi assegnata a ciascun tipo di dati. Ciò dipenderà dal valore effettivo della parte frazionaria.

Nell'esempio precedente, entrambi i tipi di dati utilizzavano la stessa precisione di secondi frazionari. Questo perché non ho specificato una scala (per definire la loro precisione) e quindi entrambi hanno usato i loro valori di scala predefiniti (entrambi sono 7).

Giusto per essere chiari, scala è il numero di cifre a destra della virgola decimale in un numero. Precisione è il numero totale di cifre nel numero.

Ad ogni modo, in quell'esempio ho assegnato solo 6 decimali al valore iniziale, quindi alla fine viene aggiunto uno zero.

Ecco cosa succede se specifico una precisione maggiore per il tempo valore rispetto a datetime2 valore:

DECLARE @thetime time(7);
SET @thetime = '23:15:59.1234567';
SELECT 
  @thetime AS 'time',
  CAST(@thetime AS datetime2(4)) AS 'datetime2(4)';

Risultato:

+------------------+--------------------------+
| time             | datetime2(4)             |
|------------------+--------------------------|
| 23:15:59.1234567 | 1900-01-01 23:15:59.1235 |
+------------------+--------------------------+

Specificando una scala da 4 a datetime2 value, il risultato viene ridotto a 4 cifre decimali e in questo caso viene arrotondato per eccesso.

Come ci si potrebbe aspettare, non è solo la parte frazionaria che può essere arrotondata. Ecco un esempio di dove la parte frazionaria determina l'arrotondamento per eccesso di minuti e secondi:

DECLARE @thetime time(7);
SET @thetime = '23:15:59.7654321';
SELECT 
  @thetime AS 'time',
  CAST(@thetime AS datetime2(0)) AS 'datetime2(0)';

Risultato:

+------------------+---------------------+
| time             | datetime2(0)        |
|------------------+---------------------|
| 23:15:59.7654321 | 1900-01-01 23:16:00 |
+------------------+---------------------+

Tuttavia, è possibile ottenere risultati diversi per gli stessi dati modificando la precisione. Se aumentiamo la precisione, anche solo di un decimale, otteniamo questo:

DECLARE @thetime time(7);
SET @thetime = '23:15:59.7654321';
SELECT 
  @thetime AS 'time',
  CAST(@thetime AS datetime2(1)) AS 'datetime2(1)';

Risultato:

+------------------+-----------------------+
| time             | datetime2(1)          |
|------------------+-----------------------|
| 23:15:59.7654321 | 1900-01-01 23:15:59.8 |
+------------------+-----------------------+

Quindi in questo caso i minuti e i secondi non erano arrotondato per eccesso (ma i millisecondi erano ).

Ecco cosa succede se imposto il ora valore per utilizzare una scala di precisione inferiore a datetime2 valore.

DECLARE @thetime time(0);
SET @thetime = '23:15:59.004007';
SELECT 
  @thetime AS 'time',
  CAST(@thetime AS datetime2) AS 'datetime2';

Risultato:

+----------+-----------------------------+
| time     | datetime2                   |
|----------+-----------------------------|
| 23:15:59 | 1900-01-01 23:15:59.0000000 |
+----------+-----------------------------+

E già che ci siamo, ecco un esempio di dove la nostra scala di precisione può comportare l'arrotondamento della data al giorno successivo:

DECLARE @thetime time(7);
SET @thetime = '23:59:59.9999999';
SELECT 
  @thetime AS 'time',
  CAST(@thetime AS datetime2(0)) AS 'datetime2(0)';

Risultato:

+------------------+---------------------+
| time             | datetime2(0)        |
|------------------+---------------------|
| 23:59:59.9999999 | 1900-01-02 00:00:00 |
+------------------+---------------------+

Esempio 3 – Conversione esplicita mediante CONVERT()

Questo è lo stesso del primo esempio, tranne che questa volta uso il CONVERT() funzione invece di CAST() .

DECLARE @thetime time;
SET @thetime = '23:15:59.004007';
SELECT 
  @thetime AS 'time',
  CONVERT(datetime2, @thetime) AS 'datetime2';

Risultato:

+------------------+-----------------------------+
| time             | datetime2                   |
|------------------+-----------------------------|
| 23:15:59.0040070 | 1900-01-01 23:15:59.0040070 |
+------------------+-----------------------------+

Esempio 4 – Conversione implicita

Ecco un esempio di come fare la stessa cosa, ma usando una conversione di tipo implicita.

DECLARE @thetime time, @thedatetime2 datetime2;
SET @thetime = '23:15:59.004007';
SET @thedatetime2 = @thetime;
SELECT 
  @thetime AS 'time',
  @thedatetime2 AS 'datetime2';

Risultato:

+------------------+-----------------------------+
| time             | datetime2                   |
|------------------+-----------------------------|
| 23:15:59.0040070 | 1900-01-01 23:15:59.0040070 |
+------------------+-----------------------------+

Quindi otteniamo lo stesso risultato, indipendentemente dal fatto che si tratti di una conversione esplicita o implicita.

Questa è una conversione implicita perché non stiamo usando una funzione di conversione per convertirla in modo esplicito. Stiamo semplicemente assegnando il valore da una variabile di un tipo di dati a una variabile di un altro tipo di dati. In questo caso, SQL Server esegue una conversione implicita dietro le quinte quando proviamo ad assegnare il tempo valore a un datetime2 variabile.

Esempio 5:modifica della data

Se devi cambiare la data (ma mantenere la stessa ora), puoi usare il DATEADD() funzione.

DECLARE @thetime time, @thedatetime2 datetime2;
SET @thetime = '23:15:59.004007';
SET @thedatetime2 = @thetime;
SET @thedatetime2 = DATEADD(year, 120, @thedatetime2);
SELECT 
  @thetime AS 'time',
  @thedatetime2 AS 'datetime2';

Risultato:

+------------------+-----------------------------+
| time             | datetime2                   |
|------------------+-----------------------------|
| 23:15:59.0040070 | 2020-01-01 23:15:59.0040070 |
+------------------+-----------------------------+

In questo caso aggiungo 120 al valore dell'anno, che lo porta al 2020.