Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

datetime vs smalldatetime w SQL Server:jaka jest różnica?

W tym artykule omówiono główne różnice między data i godziną i smalldatetime typy danych w SQL Server.

Oba typy danych są używane do przechowywania wartości daty i godziny, jednak istnieją między nimi różnice. W większości przypadków lepiej jest unikać obu typów i używać datetime2 zamiast tego (Microsoft również to zaleca). W każdym razie, oto porównanie tych dwóch typów danych.

Poniższa tabela przedstawia niektóre kluczowe podobieństwa i różnice między tymi dwoma typami danych.

Funkcja smalldatetime data i godzina
Zgodny z SQL (ANSI i ISO 8601) Nie Nie
Zakres dat 1900-01-01 do 2079-06-06 1753-01-01 do 9999-12-31
Zakres czasu 00:00:00 do 23:59:59 00:00:00 do 23:59:59,997
Długość znaku maksymalnie 19 pozycji Minimalnie 19 pozycji
Maksymalnie 23
Rozmiar pamięci 4 bajty, stałe 8 bajtów, stałe
Dokładność Jedna minuta Zaokrąglone do przyrostów o 0,000, 0,003 lub 0,007 sekundy
Ułamkowa druga precyzja Nie Tak
Zdefiniowana przez użytkownika precyzja ułamkowa sekundy Nie Nie
Przesunięcie strefy czasowej Brak Brak
Świadomość i zachowanie przesunięcia strefy czasowej Nie Nie
Świadomość czasu letniego Nie Nie

Czy powinienem używać „datetime” czy „smalldatetime”?

Firma Microsoft odradza używanie obu tych typów danych w nowych pracach. Powinieneś ich używać tylko wtedy, gdy masz ku temu silny powód.

Ale gdybyś musiał wybrać, prawdopodobnie Twoja decyzja zostałaby podjęta przez rozważenie dodatkowej precyzji i dokładności data-godzina w porównaniu z niższymi wymaganiami dotyczącymi pamięci smalldatetime .

Innymi słowy, jeśli nie potrzebujesz dokładności co do sekund, smalldatetime wykona zadanie, wykorzystując tylko połowę przestrzeni dyskowej. Z drugiej strony, jeśli potrzebujesz dokładności co do sekund (lub nawet kilku ułamków sekund), musisz użyć datetime .

W każdym razie firma Microsoft zaleca użycie daty , czas , datagodzina2 lub przesunięcie daty i godziny do nowej pracy.

Zobacz smalldatetime a data/godzina2 i data i godzina a data/godzina2 aby zobaczyć, jak każdy z tych typów wypada w porównaniu z datetime2 .

Przykład 1 – Porównanie podstawowe

Oto krótki przykład pokazujący podstawową różnicę między datetime i 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';

Wynik:

+-------------------------+---------------------+
| datetime                | smalldatetime       |
|-------------------------+---------------------|
| 2025-05-21 10:15:30.557 | 2025-05-21 10:16:00 |
+-------------------------+---------------------+

Tutaj ustawiam smalldatetime zmienna na taką samą wartość jak data i godzina zmienny. Powoduje to przekonwertowanie wartości na smalldatetime a następnie możemy użyć SELECT oświadczenie, aby zobaczyć rzeczywistą wartość, która została przypisana do każdej zmiennej.

W tym przypadku obie zmienne zaokrąglają wartość. Ale są one zaokrąglane inaczej.

data i godzina zmienna zaokrągla w górę część ułamkową sekund. Dzieje się tak, ponieważ data i godzina zawsze zaokrągla z dokładnością do 0,000, 0,003 lub 0,007 sekundy.

smalldatetime z drugiej strony, zaokrągla minuty część. Mało tego, druga część jest ustawiona na zero. Należy się tego spodziewać, ponieważ oficjalna dokumentacja Microsoft stwierdza, że ​​smalldatetime czas jest … oparty na dobie 24-godzinnej, z sekundami zawsze zerowymi (:00) i bez ułamków sekund .

Widzimy więc, że data i godzina typ zapewnia dokładniejszą i dokładniejszą wartość daty/czasu.

Przykład 2 – ustawianie wartości z literałów łańcuchowych

W poprzednich przykładach smalldateime wartość została przypisana przez ustawienie jej na taką samą wartość jak data-godzina wartość. Kiedy to robimy, SQL Server wykonuje niejawną konwersję, aby dane „dopasowały się” do nowego typu danych.

Jak się okazuje, możemy również ustawić smalldatetime zmiennej do tego samego literału ciągu, który zawiera ułamki sekund (nawet jeśli ten typ danych nie przechowuje ułamków sekund).

Oto przykład, w którym to robię:

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

Wynik:

+-------------------------+---------------------+
| datetime                | smalldatetime       |
|-------------------------+---------------------|
| 2025-05-21 10:15:30.557 | 2025-05-21 10:16:00 |
+-------------------------+---------------------+

Oczywiście wynik jest taki sam, gdy wybieramy wartości – smalldatetime wartość nie pokazuje żadnych ułamków sekund, sekundy wynoszą zero, a minuty są zaokrąglane w górę.

Jeśli jednak użyjemy więcej niż 3 miejsc po przecinku, oba typy danych zwrócą błąd.

Błąd data i godzina :

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

Wynik:

Msg 241, Level 16, State 1, Line 4
Conversion failed when converting date and/or time from character string.

Błąd dla 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';

Wynik:

Msg 295, Level 16, State 3, Line 5
Conversion failed when converting character string to smalldatetime data type.

Przykład 3 – Rozmiar pamięci

smalldatetime typ danych ma stały rozmiar pamięci wynoszący 4 bajty. To jedna z niewielu korzyści smalldatetime ma ponad data i godzina , który ma stały rozmiar pamięci wynoszący 8 bajtów.

Możemy sprawdzić rozmiar pamięci za pomocą DATALENGTH() funkcja zwracająca liczbę bajtów użytych dla każdej z naszych wartości:

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

Wynik

+------------+-----------------+
| datetime   | smalldatetime   |
|------------+-----------------|
| 8          | 4               |
+------------+-----------------+

Otrzymujemy również ten sam wynik, nawet jeśli przekonwertujemy je na varbinary , który jest bardziej reprezentatywny dla tego, jak są one faktycznie przechowywane w bazie danych:

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

Wynik

+------------+-----------------+
| datetime   | smalldatetime   |
|------------+-----------------|
| 8          | 4               |
+------------+-----------------+

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Oblicz skrót MD5 ciągu UTF8

  2. Łączenie ciągów SQL Server z wartością Null

  3. Jak zmienić domyślny język dla SQL Server?

  4. Nieudane wywołanie ODBC z procedurą składowaną — zapytanie przekazujące

  5. WHERE IS NULL, IS NOT NULL lub NO WHERE w zależności od wartości parametru SQL Server