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

SqlDateTime.MinValue !=DateTime.MinValue, hvorfor?

Jeg tror, ​​at forskellen mellem SQL's og .NET's Dato datatyper stammer fra det faktum, at SQL Servers datetime datatype, det er minimums- og maksimumværdier, og dets præcision er meget ældre end .NET's DateTime-datatype.

Med fremkomsten af ​​.NET besluttede teamet, at Datetime-datatypen skulle have en mere naturlig minimumsværdi, og 01/01/0001 virker et ret logisk valg, og bestemt fra et programmeringssprog , i stedet for database perspektiv, er denne værdi mere naturlig.

Med SQL Server 2008 er der i øvrigt en række nye Dato-baserede datatyper (Dato, Time, DateTime2, DateTimeOffset), som faktisk tilbyder en øget rækkevidde og præcision, og som er tæt knyttet til DateTime-datatypen i .NET. Datatypen DateTime2 har f.eks. et datointerval fra 0001-01-01 til 9999-12-31.

Standard "datetime" datatypen for SQL Server har altid haft en minimumsværdi på 01/01/1753 (og har faktisk stadig!). Jeg må indrømme, at jeg også var nysgerrig efter betydningen af ​​denne værdi, så jeg gravede lidt. Det jeg fandt var som følger:

I perioden mellem 1 e.Kr. og i dag har den vestlige verden faktisk brugt to hovedkalendere:Julius Cæsars julianske kalender og pave Gregor XIII's gregorianske kalender. De to kalendere adskiller sig kun med hensyn til én regel:reglen for at bestemme, hvad et skudår er. I den julianske kalender er alle år deleligt med fire skudår. I den gregorianske kalender er alle år deleligt med fire skudår, bortset fra at år deleligt med 100 (men ikke deleligt med 400) ikke er skudår. Årene 1700, 1800 og 1900 er således skudår i den julianske kalender, men ikke i den gregorianske kalender, mens årene 1600 og 2000 er skudår i begge kalendere.

Da pave Gregor XIII introducerede sin kalender i 1582, instruerede han også, at dagene mellem den 4. oktober 1582 og den 15. oktober 1582 skulle springes over – det vil sige, at han sagde, at dagen efter den 4. oktober skulle være den 15. oktober. Mange lande dog forsinket med at skifte. England og hendes kolonier skiftede ikke fra juliansk til gregoriansk opgørelse før 1752, så for dem var de oversprungne datoer mellem 4. september og 14. september 1752. Andre lande skiftede på andre tidspunkter, men 1582 og 1752 er de relevante datoer for DBMS'er, som vi diskuterer.

Der opstår således to problemer med datoregning, når man går mange år tilbage. Den første er, skal skudår før skiftet beregnes efter de julianske eller gregorianske regler? Det andet problem er, hvornår og hvordan skal de oversprungne dage håndteres?

Sådan håndterer Big Eight DBMS disse spørgsmål:

  • Lad som om der ikke var nogen kontakt. Dette er, hvad SQL-standarden ser ud til at kræve, selvom standarddokumentet er uklart:Det siger bare, at datoer er "begrænset af de naturlige regler for datoer ved brug af den gregorianske kalender" - uanset hvad "naturlige regler" er. Dette er den mulighed, som DB2 valgte. Når der er en foregivelse af, at en enkelt kalenders regler altid har været gældende, selv på tidspunkter, hvor ingen har hørt om kalenderen, er den tekniske term, at en "proleptisk" kalender er i kraft. Så vi kunne for eksempel sige, at DB2 følger en proleptisk gregoriansk kalender.

  • Undgå problemet helt. Microsoft og Sybase satte deres minimumsdatoværdier til 1. januar 1753, sikkert efter det tidspunkt, hvor Amerika skiftede kalendere. Dette kan forsvares, men fra tid til anden dukker der klager op over, at disse to DBMS'er mangler en brugbar funktionalitet, som de andre DBMS'er har, og som SQL-standarden kræver.

  • Vælg 1582. Dette er, hvad Oracle gjorde. En Oracle-bruger ville opdage, at det dato-aritmetiske udtryk 15. oktober 1582 minus 4. oktober 1582 giver en værdi på 1 dag (fordi 5-14 oktober ikke eksisterer), og at datoen 29. februar 1300 er gyldig (fordi det julianske spring- årsreglen gælder). Hvorfor fik Oracle ekstra problemer, når SQL-standarden ikke ser ud til at kræve det? Svaret er, at brugerne kan kræve det. Historikere og astronomer bruger dette hybridsystem i stedet for en proleptisk gregoriansk kalender. (Dette er også den standardindstilling, som Sun valgte ved implementering af GregorianCalendar-klassen til Java – på trods af navnet er GregorianCalendar en hybridkalender.)

Dette citat ovenfor er taget fra følgende link:

SQL Performance Tuning:Datoer i SQL



  1. Sådan får du maks. værdi af kolonnetype heltal gemt som typetekst i SQLite-tabel

  2. 2 måder at oprette en tabel på, hvis den ikke allerede findes i Oracle

  3. Hvordan får jeg en kolonne med fortløbende, stigende tal, uden at der mangler nogle tal?

  4. SQL-forespørgsel - Sammenkædning af resultater i én streng