Den här artikeln undersöker de viktigaste skillnaderna mellan datetime och smalldatetime datatyper i SQL Server.
Båda datatyperna används för att lagra datum- och tidsvärden, men det finns skillnader mellan de två. I de flesta fall är det bättre att undvika båda typerna och använda datetime2 istället (Microsoft rekommenderar också detta). I alla fall, här är en jämförelse av dessa två datatyper.
Följande tabell beskriver några viktiga likheter och skillnader mellan dessa två datatyper.
Funktion | smalldatetime | datumtid |
---|---|---|
SQL-kompatibel (ANSI &ISO 8601) | Nej | Nej |
Datumintervall | 1900-01-01 till 2079-06-06 | 1753-01-01 till 9999-12-31 |
Tidsintervall | 00:00:00 till 23:59:59 | 00:00:00 till 23:59:59.997 |
Teckenlängd | max 19 positioner | 19 positioner minst 23 max |
Lagringsstorlek | 4 byte, fast | 8 byte, fast |
Noggrannhet | En minut | Avrundat till steg om 0,000, 0,003 eller 0,007 sekunder |
Bråkdelssekundprecision | Nej | Ja |
Användardefinierad precision på bråkdelssekunder | Nej | Nej |
Tidszonsförskjutning | Inga | Inga |
Medveten om och bevarande av tidszonförskjutning | Nej | Nej |
Medveten om sommartid | Nej | Nej |
Ska jag använda 'datetime' eller 'smalldatetime'?
Microsoft rekommenderar att du inte använder båda dessa datatyper för nytt arbete. Du bör bara använda dem om du har en stark anledning till det.
Men om du var tvungen att välja, skulle ditt beslut troligen fattas genom att väga upp den extra precisionen och noggrannheten för datetime jämfört med de lägre lagringskraven för smalldatetime .
Med andra ord, om du inte behöver noggrannhet till sekunderna, smalldatetime kommer att göra jobbet medan du bara använder halva lagringsutrymmet. Å andra sidan, om du behöver noggrannhet till sekunderna (eller till och med några bråkdelar), måste du använda datetime .
I alla fall rekommenderar Microsoft att du använder datum , tid , datetime2 , eller datumtidsförskjutning för nytt arbete.
Se smalldatetime kontra datetime2 och datumtid kontra datetime2 för att se hur var och en av dessa typer jämförs med datetime2 .
Exempel 1 – Grundläggande jämförelse
Här är ett snabbt exempel för att visa den grundläggande skillnaden mellan datetime och smalldatetime .
DECLARE @thedatetime datetime, @thesmalldatetime smalldatetime; SET @thedatetime = '2025-05-21 10:15:30.555'; SET @thesmalldatetime = @thedatetime; SELECT @thedatetime AS 'datetime', @thesmalldatetime AS 'smalldatetime';
Resultat:
+-------------------------+---------------------+ | datetime | smalldatetime | |-------------------------+---------------------| | 2025-05-21 10:15:30.557 | 2025-05-21 10:16:00 | +-------------------------+---------------------+
Här ställer jag in en smalldatetime variabel till samma värde som datetime variabel. Detta gör att värdet konverteras till smalldatetime och vi kan sedan använda en SELECT
uttalande för att se det faktiska värdet som tilldelades varje variabel.
I det här fallet avrundar båda variablerna värdet uppåt. Men de avrundas annorlunda.
datetime variabel rundar upp bråkdelssekundersdelen. Detta beror på att datetime avrundar alltid till steg om 0,000, 0,003 eller 0,007 sekunder.
smalldatetime variabel å andra sidan, avrundar minuterna uppåt del. Inte nog med det, sekunddelen är nollställd. Detta är att vänta, eftersom Microsofts officiella dokumentation säger att smalldatetime
sin tid är ...baserad på en 24-timmarsdygn, med sekunder alltid noll (:00) och utan bråkdelar
.
Så vi kan se att datetime typ ger ett mer exakt och exakt datum/tidsvärde.
Exempel 2 – Ställa in värden från strängbokstaver
I de tidigare exemplen, smalldatetime värde tilldelades genom att sätta det till samma värde som datetime värde. När vi gör det utför SQL Server en implicit konvertering för att data ska "passa" till den nya datatypen.
Som det visar sig kan vi också ställa in smalldatetime variabel till samma strängliteral som inkluderar bråkdelar (även om denna datatyp inte lagrar bråkdelar).
Här är ett exempel där jag gör just det:
DECLARE @thedatetime datetime, @thesmalldatetime smalldatetime; SET @thedatetime = '2025-05-21 10:15:30.555'; SET @thesmalldatetime = '2025-05-21 10:15:30.555'; SELECT @thedatetime AS 'datetime', @thesmalldatetime AS 'smalldatetime';
Resultat:
+-------------------------+---------------------+ | datetime | smalldatetime | |-------------------------+---------------------| | 2025-05-21 10:15:30.557 | 2025-05-21 10:16:00 | +-------------------------+---------------------+
Naturligtvis blir resultatet detsamma när vi väljer värdena – smalldatetime värdet visar inte några bråkdelar av sekunder, sekunderna är noll och minuterna avrundas uppåt.
Men om vi använder mer än 3 decimaler kommer båda datatyperna att returnera ett fel.
Fel för datetime :
DECLARE @thedatetime datetime, @thesmalldatetime smalldatetime; SET @thedatetime = '2025-05-21 10:15:30.5555'; SET @thesmalldatetime = '2025-05-21 10:15:30.5555'; SELECT @thedatetime AS 'datetime', @thesmalldatetime AS 'smalldatetime';
Resultat:
Msg 241, Level 16, State 1, Line 4 Conversion failed when converting date and/or time from character string.
Fel för smalldatetime :
DECLARE @thedatetime datetime, @thesmalldatetime smalldatetime; SET @thedatetime = '2025-05-21 10:15:30.5555'; SET @thesmalldatetime = '2025-05-21 10:15:30.5555'; SELECT @thedatetime AS 'datetime', @thesmalldatetime AS 'smalldatetime';
Resultat:
Msg 295, Level 16, State 3, Line 5 Conversion failed when converting character string to smalldatetime data type.
Exempel 3 – Lagringsstorlek
smalldatetime datatypen har en fast lagringsstorlek på 4 byte. Detta är en av få fördelar smalldatetime har över datumtid , som har en fast lagringsstorlek på 8 byte.
Vi kan kontrollera lagringsstorleken med DATALENGTH()
funktion för att returnera antalet byte som används för vart och ett av våra värden:
DECLARE @thedatetime datetime, @thesmalldatetime smalldatetime; SET @thedatetime = '2025-05-21 10:15:30.123'; SET @thesmalldatetime = @thedatetime; SELECT DATALENGTH(@thedatetime) AS 'datetime', DATALENGTH(@thesmalldatetime) AS 'smalldatetime';
Resultat
+------------+-----------------+ | datetime | smalldatetime | |------------+-----------------| | 8 | 4 | +------------+-----------------+
Vi får också samma resultat även om vi konverterar dem till varbinary , vilket är mer representativt för hur de faktiskt lagras i databasen:
DECLARE @thedatetime datetime, @thesmalldatetime smalldatetime; SET @thedatetime = '2025-05-21 10:15:30.123'; SET @thesmalldatetime = @thedatetime; SELECT DATALENGTH(CAST(@thedatetime AS varbinary(10))) AS 'datetime', DATALENGTH(CAST(@thesmalldatetime AS varbinary(10))) AS 'smalldatetime';
Resultat
+------------+-----------------+ | datetime | smalldatetime | |------------+-----------------| | 8 | 4 | +------------+-----------------+