sql >> Databasteknik >  >> RDS >> Sqlserver

Konvertera 'tid' till 'datetime2' i SQL Server (T-SQL-exempel)

Den här artikeln innehåller exempel på hur du konverterar en tid värde till en datetime2 värde i SQL Server.

När du konverterar en tid värde till datetime2 , extra information läggs till värdet. Detta beror på att datetime2 datatypen innehåller information om både datum och tid. tiden datatyp, å andra sidan, innehåller endast tidsinformation.

Mer specifikt är datumet satt till '1900-01-01' (såvida det inte råkar avrundas uppåt till '1900-01-02'), tidskomponenten kopieras, och enligt Microsofts dokumentation, tidszonförskjutningen är inställd på 00:00 (även om datetime2 datatypen är inte tidszonsmedveten och bevarar inte någon tidszonsförskjutning).

När bråkdelssekunderprecisionen för datetime2(n) värdet är större än tid(n) värde, värdet avrundas uppåt.

Exempel 1 – Explicit konvertering med CAST()

Här är ett exempel på en explicit konvertering. I det här fallet använder jag CAST() funktion direkt inom SELECT uttalande för att uttryckligen konvertera från tid till datetime2 .

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

Resultat:

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

När du konverterar från tid till datetime2 , läggs en datumkomponent till och ställs in på 1900-01-01 .

Det finns dock scenarier där datumet kan avrundas uppåt till 1900-01-02 . Detta beror på bråkdelssekunderna och vilken precision du använder. Se nedan för ett exempel på detta.

Exempel 2 – Bråkdelssekunderprecision

Du kan få olika resultat beroende på bråksekundersprecisionen som är tilldelad varje datatyp. Detta beror på det faktiska värdet av deldelen.

I det föregående exemplet använde båda datatyperna samma bråksekundersprecision. Detta beror på att jag inte angav en skala (för att definiera deras precision) och därför använde de båda sina standardskalvärden (båda råkar vara 7).

Bara för att vara tydlig, skala är antalet siffror till höger om decimalkomma i ett tal. Precision är det totala antalet siffror i numret.

Hur som helst, i det exemplet tilldelade jag bara 6 decimaler till startvärdet, därför läggs en nolla till i slutet.

Här är vad som händer om jag anger en högre precision för tiden värde jämfört med datetime2 värde:

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

Resultat:

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

Genom att ange en skala på 4 till datetime2 värdet reduceras resultatet till 4 decimaler, och i det här fallet avrundas det uppåt.

Som du kanske förväntar dig är det inte bara bråkdelen som kan avrundas uppåt. Här är ett exempel på var bråkdelen gör att minuter och sekunder avrundas uppåt:

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

Resultat:

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

Du kan dock få olika resultat för samma data genom att ändra precisionen. Om vi ​​ökar precisionen, till och med bara med en decimal, får vi detta:

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

Resultat:

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

Så i det här fallet var minuterna och sekunderna inte avrundat uppåt (men millisekunder var ).

Här är vad som händer om jag ställer in tiden värde för att använda en lägre precisionsskala än datetime2 värde.

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

Resultat:

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

Och medan vi ändå håller på, här är ett exempel på var vår precisionsskala kan resultera i att bråkdelar av sekunder gör att datumet avrundas till nästa dag:

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

Resultat:

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

Exempel 3 – Explicit konvertering med CONVERT()

Detta är samma som det första exemplet, förutom att den här gången använder jag CONVERT() funktion istället för CAST() .

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

Resultat:

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

Exempel 4 – Implicit konvertering

Här är ett exempel på att göra samma sak, men med en implicit typkonvertering.

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

Resultat:

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

Så vi får samma resultat, oavsett om det är en explicit eller implicit konvertering.

Detta är en implicit konvertering eftersom vi inte använder en konverteringsfunktion för att explicit konvertera den. Vi tilldelar helt enkelt värdet från en variabel av en datatyp till en variabel av en annan datatyp. I det här fallet utför SQL Server en implicit konvertering bakom kulisserna när vi försöker tilldela tiden värde till en datetime2 variabel.

Exempel 5 – Ändra datum

Om du behöver ändra datumet (men behålla samma tid), kan du använda DATEADD() fungera.

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

Resultat:

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

I det här fallet lägger jag till 120 till årsvärdet, vilket leder till 2020.


  1. Du, vem äger det där #temp-bordet?

  2. SQLite JSON_REMOVE()

  3. Hur gör man en bulkinsert i MySQL?

  4. Hur man får senaste 1 timmes data i MySQL