Denne artikel indeholder eksempler på konvertering af en tid værdi til en datetime2 værdi i SQL Server.
Når du konverterer en tid værdi til datetime2 , tilføjes ekstra information til værdien. Dette skyldes, at datetime2 datatypen indeholder både dato- og tidsinformation. tidspunktet datatype indeholder på den anden side kun tidsinformation.
Mere specifikt er datoen sat til '1900-01-01' (medmindre den tilfældigvis bliver rundet op til '1900-01-02'), tidskomponenten kopieres, og i henhold til Microsoft-dokumentationen forskydes tidszonen er indstillet til 00:00 (selvom datetime2 datatypen er ikke tidszonebevidst og bevarer ingen tidszoneforskydning).
Når brøksekunders præcision af datetime2(n) værdien er større end tid(n) værdi, er værdien rundet op.
Eksempel 1 – Eksplicit konvertering ved hjælp af CAST()
Her er et eksempel på en eksplicit konvertering. I dette tilfælde bruger jeg CAST()
funktion direkte i SELECT
sætning for eksplicit at konvertere fra tid til 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 konverterer fra tid til datetime2 , tilføjes en datokomponent og indstilles til 1900-01-01
.
Der er dog scenarier, hvor datoen kan rundes op til 1900-01-02
. Dette vil afhænge af brøkdelen af sekunder og hvilken præcision du bruger. Se nedenfor for et eksempel på dette.
Eksempel 2 – Brøkdele sekunders præcision
Du kan få forskellige resultater afhængigt af den brøkdelsekunders præcision, der er tildelt hver datatype. Dette vil afhænge af den faktiske værdi af brøkdelen.
I det foregående eksempel brugte begge datatyper den samme brøksekunderpræcision. Dette skyldes, at jeg ikke specificerede en skala (for at definere deres præcision), og derfor brugte de begge deres standardskalaværdier (begge er tilfældigvis 7).
Bare for at være klar, skaler er antallet af cifre til højre for decimaltegnet i et tal. Nøjagtighed er det samlede antal cifre i tallet.
I hvert fald, i det eksempel tildelte jeg kun 6 decimaler til startværdien, derfor tilføjes et nul til slutningen.
Her er, hvad der sker, hvis jeg angiver en højere præcision for tiden værdi sammenlignet med datetime2 værdi:
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 | +------------------+--------------------------+
Ved at angive en skala fra 4 til datetime2 værdi reduceres resultatet til 4 decimaler, og i dette tilfælde rundes det op.
Som du måske forventer, er det ikke kun brøkdelen, der kan blive rundet op. Her er et eksempel på, hvor brøkdelen får minutter og sekunder til at blive rundet op:
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 dog få forskellige resultater for de samme data ved at ændre præcisionen. Hvis vi øger præcisionen, endda kun med én decimal, får vi dette:
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 dette tilfælde var minutterne og sekunderne ikke rundet op (men millisekunder var ).
Her er, hvad der sker, hvis jeg indstiller tidspunktet værdi for at bruge en skala med lavere præcision end datetime2 værdi.
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 | +----------+-----------------------------+
Og mens vi er i gang, er her et eksempel på, hvor vores præcisionsskala kan resultere i, at brøkdelen af sekunder forårsager, at datoen afrundes til næste 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 | +------------------+---------------------+
Eksempel 3 – Eksplicit konvertering ved hjælp af CONVERT()
Dette er det samme som det første eksempel, bortset fra at denne gang bruger jeg CONVERT()
funktion i stedet for 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 | +------------------+-----------------------------+
Eksempel 4 – Implicit konvertering
Her er et eksempel på at gøre det samme, men ved at bruge en implicit typekonvertering.
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 det samme resultat, uanset om det er en eksplicit eller implicit konvertering.
Dette er en implicit konvertering, fordi vi ikke bruger en konverteringsfunktion til eksplicit at konvertere den. Vi tildeler simpelthen værdien fra en variabel af én datatype til en variabel af en anden datatype. I dette tilfælde udfører SQL Server en implicit konvertering bag kulisserne, når vi forsøger at tildele tidspunktet værdi til en datetime2 variabel.
Eksempel 5 – Skift datoen
Hvis du har brug for at ændre datoen (men beholde den samme tid), kan du bruge DATEADD()
fungere.
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 dette tilfælde tilføjer jeg 120 til årsværdien, hvilket bringer den til 2020.