Data: 19.06.2025

Typy danych w MS SQL Server
Spis treści
- Typy danych w MS SQL Server
- Typy danych w MS SQL Server
- Kategorie typów danych
- Dokładne typy numeryczne w SQL Server
- Przybliżone typy numeryczne
- Typy daty i czasu w SQL Server
- Typ znakowy – łańcuchy znaków i łańcuchy znaków Unicode
- Ciągi binarne
- Typy danych specjalnego przeznaczenia
- Łączenie wyrażeń różnych typów w MS SQL Server
- Priorytety typów danych
- Typy danych SQL Server tworzone przez użytkownika
- Jaki jest cel tworzenia typów danych użytkownika?
W artykule Typy danych w MS SQL Server przedstawiam informacje, w jaki sposób używać typów danych w zapytaniach SQL.
Typy danych to jeden z fundamentów bazy danych. W Microsoft SQL Server pełnią kluczową rolę w definiowaniu struktury danych, wpływają na wydajność zapytań oraz integralność danych i sposób ich przechowywania.
Typy danych w MS SQL Server
Typ danych to atrybut określający rodzaj danych, które dany obiekt może przechowywać np. dane liczbowe, znakowe, pieniężne, daty i godziny.
Kategorie typów danych
Typy danych w SQL Server możemy podzielić na kilka głównych kategorii. Każda kategoria odpowiada innemu rodzajowi informacji.
- Dokładne typy numeryczne (Exact numerics)
- Przybliżone typy numeryczne (Approximate numerics)
- Typy daty i czasu (Date and time)
- Łańcuchy znaków (Character strings)
- Ciągi binarne (Binary strings)
- Inne typy danych (Other data types)
- Typy danych o dużej wartości (Large value data types): varchar(max), nvarchar(max)
- Typy danych dużych obiektów (Large object data types): text, ntext, image, varbinary(max), xml
Dokładne typy numeryczne w SQL Server
Dokładne typy numeryczne w SQL Server służą do przechowywania liczb, które wymagają pełnej precyzji i dokładności, bez zaokrągleń czy błędów przybliżenia. Są szczególnie istotne w systemach finansowych, księgowych, magazynowych czy wszędzie tam, gdzie nawet najmniejsza strata precyzji może prowadzić do błędnych obliczeń.
SQL Server oferuje następujące dokładne typy numeryczne:
| Typ danych | Zakres wartości | Rozmiar | Opis i zastosowanie |
|---|---|---|---|
tinyint | 0 do 255 | 1 bajt | Małe liczby całkowite, tylko dodatnie. Stosowany do statusów, poziomów dostępu, flag logicznych. |
smallint | -32 768 do 32 767 | 2 bajty | Średnie liczby całkowite. Idealny do przechowywania lat produkcji, liczb porządkowych. |
int | -2 147 483 648 do 2 147 483 647 | 4 bajty | Najczęściej stosowany typ całkowity. Używany dla kluczy głównych, liczby produktów itp. |
bigint | -9 223 372 036 854 775 808 do 9 223 372 036 854 775 807 | 8 bajtów | Bardzo duże liczby całkowite. Przykłady użycia: liczniki zdarzeń, globalne identyfikatory. |
decimal(p, s) numeric(p, s) | -10^38+1 do 10^38-1 | 5–17 bajtów (zależnie od p) | Liczby dziesiętne o stałej precyzji i skali. Używane w finansach – ceny, kwoty, kalkulacje księgowe. |
money | -922 337 203 685 477.5808 do 922 337 203 685 477.5807 | 8 bajtów | Typ finansowy z dokładnością do 4 miejsc po przecinku. Przechowuje salda kont, budżety. |
smallmoney | -214 748.3648 do 214 748.3647 | 4 bajty | Jak money, ale z mniejszym zakresem. Nadaje się do cen jednostkowych i drobnych transakcji. |
bit | 0, 1 lub NULL | 1 bit (pakowany) | Typ logiczny – reprezentuje wartości PRAWDA/FAŁSZ. Idealny do flag aktywności, kolumn typu „czy dotyczy”. |
Typy danych decimal i numeric są identyczne.
Przybliżone typy numeryczne
Przybliżone typy numeryczne służą do przechowywania liczb zmiennoprzecinkowych, czyli takich, które mogą zawierać bardzo duże lub bardzo małe wartości oraz liczby po przecinku. W przeciwieństwie do typów dokładnych (decimal, int itd.), tego rodzaju dane nie gwarantują pełnej precyzji – mogą wystąpić niewielkie błędy zaokrągleń.
Typy float i real są używane tam, gdzie dokładność nie jest najważniejsza, ale istotny jest duży zakres wartości lub szybkość obliczeń – na przykład w analizach naukowych, danych pomiarowych, systemach telemetrycznych lub grafice komputerowej.
| Typ danych | Zakres wartości (przybliżony) | Rozmiar | Opis i zastosowanie |
|---|---|---|---|
float(n) | ±1.79E+308 (dla float(53)) ±3.40E+38 (dla float(24)) | 4 lub 8 bajtów (zależnie od precyzji n) | Typ zmiennoprzecinkowy o binarnej precyzji od 1 do 53 (domyślnie n = 53). Stosowany w danych pomiarowych, obliczeniach naukowych i modelach symulacyjnych. |
real | ±3.40E+38 | 4 bajty | Lżejszy i mniej precyzyjny odpowiednik float, odpowiada float(24). Używany w grach komputerowych, danych telemetrycznych i grafice. |
Typy daty i czasu w SQL Server
Typy daty i czasu w SQL Server umożliwiają przechowywanie informacji związanych z kalendarzem i zegarem – takich jak daty urodzenia, terminy dostaw, godziny logowania, przedziały czasowe, a nawet znaczniki czasu z precyzją do części sekundy.
W zależności od potrzeb możesz wybrać typ zawierający tylko datę, tylko czas, pełen znacznik daty i czasu, a nawet datę wraz z przesunięciem strefy czasowej.
SQL Server oferuje zarówno nowoczesne, precyzyjne typy (date, datetime2, datetimeoffset), jak i starsze (datetime, smalldatetime), które nadal są spotykane w starszych systemach.
| Typ danych | Zakres danych | Dokładność | Rozmiar | Opis i zastosowanie |
|---|---|---|---|---|
date | 0001-01-01 do 9999-12-31 | 1 dzień | 3 bajty | Przechowuje tylko datę (bez godziny). Idealny do dat urodzenia, dat ważności, kalendarzy i harmonogramów. |
time(p) | 00:00:00.0000000 do 23:59:59.9999999 | od 0 do 7 cyfr po przecinku | 3–5 bajtów | Przechowuje tylko czas (bez daty), z precyzją do 100 ns. Używany do godzin otwarcia, logów systemowych i pomiaru czasu. |
datetime | 1753-01-01 do 9999-12-31 | 1/300 sekundy | 8 bajtów | Klasyczny typ przechowujący datę i godzinę, ale o ograniczonej precyzji. Stosowany np. w historii zmian, datach zamówień. |
smalldatetime | 1900-01-01 do 2079-06-06 | 1 minuta | 4 bajty | Lżejsza wersja datetime o niższej dokładności. Nadaje się do terminów spotkań, prostych logów i zapisów zdarzeń. |
datetime2(p) | 0001-01-01 do 9999-12-31 | od 0 do 7 cyfr po przecinku | 6–8 bajtów | Nowoczesny typ z datą i czasem, oferujący większą precyzję i elastyczność niż datetime. Doskonały do systemów rejestracji zdarzeń i rozliczeń. |
datetimeoffset(p) | jak datetime2 + strefa czasowa | jak datetime2 | 8–10 bajtów | Rozszerzenie datetime2 z obsługą przesunięcia UTC. Używany w systemach globalnych i danych wymagających informacji o strefie czasowej. |
Warto używać typu datetime2 a nie datetime, gdyż jest on dokładniejszy i bardziej efektywny pod względem oszczędności pamięci.
Warto również pamiętać o zapisywaniu daty w formacie yyyyMMdd, gdyż jest to format neutralny dla różnych ustawień regionalnych.
Typ znakowy – łańcuchy znaków i łańcuchy znaków Unicode
W SQL Server dane tekstowe przechowywane są jako łańcuchy znaków, które mogą być kodowane w ASCII lub Unicode.
Różnica polega na sposobie kodowania:
- łańcuchy znaków (char, varchar) kodowane w ASCII używają pojedynczego bajtu na znak (1 bajt) i są przeznaczone głównie dla języka angielskiego lub innych języków opartych na alfabecie łacińskim
- łańcuchy znaków Unicode (nchar, nvarchar) używają dwóch bajtów na znak (2 bajty) i mogą przechowywać znaki ze wszystkich języków, w tym polski, chiński, arabski czy emoji.
| Typ danych | Zakres długości | Bajty na znak | Maks. rozmiar | Opis i zastosowanie |
|---|---|---|---|---|
| char(n) | 1 do 8000 znaków | 1 bajt | 8000 B | Stała długość tekstu. Stosowane np. do kodów pocztowych, skrótów, pól stałej długości. |
| varchar(n) | 1 do 8000 znaków | 1 bajt | 8000 B | Zmienna długość tekstu. Idealne dla imion, adresów, opisów produktów. |
| varchar(max) | do ~231-1 znaków | 1 bajt | ~2 GB | Długi tekst o zmiennej długości. Używane do artykułów, wiadomości, notatek. |
| nchar(n) | 1 do 4000 znaków | 2 bajty | 8000 B | Stała długość tekstu (Unicode). Przydatne w językach azjatyckich lub gdzie ważna jest stała długość. |
| nvarchar(n) | 1 do 4000 znaków | 2 bajty | 8000 B | Zmienna długość tekstu (Unicode). Dobre dla nazwisk, tytułów, opisów z polskimi znakami. |
| nvarchar(max) | do ~230-1 znaków | 2 bajty | ~2 GB | Długi tekst Unicode. Używany do komentarzy, danych wielojęzycznych, dokumentów tekstowych. |
Od wersji SQL Server 2019 typ varchar może również przechowywać Unicode jako UTF-8.
Ciągi binarne
Ciągi binarne to specjalny typ danych w SQL Server służący do przechowywania informacji w postaci surowych danych binarnych – czyli zer i jedynek, które nie reprezentują tekstu, lecz np. pliki, obrazy, dokumenty, certyfikaty, dane szyfrowane albo niestandardowe formaty danych używane przez aplikacje.
| Typ danych | Zakres długości | Rozmiar | Opis i zastosowanie |
|---|---|---|---|
| binary(n) | 1 do 8000 bajtów | Zawsze n bajtów | Dane binarne o stałej długości. Uzupełniane zerami, jeśli dane są krótsze niż n. Przykład: hasze, kody, dane szyfrowane o znanym rozmiarze. |
| varbinary(n) | 1 do 8000 bajtów | Zależny od zawartości | Dane binarne o zmiennej długości. Zajmuje tyle miejsca, ile faktycznie potrzebuje. Przykład: obrazy profilowe, dane binarne aplikacji, pliki. |
| varbinary(max) | do 231−1 bajtów (~2 GB) | Zależny od danych | Typ przeznaczony do bardzo dużych danych binarnych. Przykład: przechowywanie dokumentów, zdjęć, filmów, załączników. |
Typy danych specjalnego przeznaczenia
SQL Server poza klasycznymi typami danych — jak liczby, tekst czy daty — oferuje również zestaw typów specjalnych, które służą do przechowywania bardziej złożonych struktur danych, takich jak dane przestrzenne, hierarchie, identyfikatory unikalne, dane binarne o automatycznej wersjonowalności, a nawet dane w formacie JSON lub XML.
Te typy są wykorzystywane w zaawansowanych aplikacjach biznesowych, geolokalizacji, systemach raportowania, grafach, replikacji, analizie danych i integracji systemów. Ich odpowiednie zastosowanie może znacznie uprościć projektowanie bazy danych i zwiększyć jej możliwości.
| Typ danych | Opis i zastosowanie |
|---|---|
| cursor | Reprezentuje wskaźnik do zestawu wyników zapytania. Przykład: iteracja po wierszach w procedurach składowanych. |
| geography | Dane przestrzenne w modelu kuli ziemskiej. Przykład: lokalizacje GPS, punkty, trasy, obszary geograficzne. |
| geometry | Dane przestrzenne w modelu płaskim (2D). Przykład: rysunki CAD, mapy, analizy przestrzenne w układzie kartezjańskim. |
| hierarchyid | Reprezentuje dane hierarchiczne (drzewiaste). Przykład: struktury organizacyjne, kategorie produktów. |
| json | Przechowuje dane w formacie JSON (tekstowym). Przykład: API, konfiguracje, dane dynamiczne w strukturze klucz-wartość. |
| vector | (Od SQL Server 2022) Reprezentuje wektory liczb zmiennoprzecinkowych. Przykład: AI, wyszukiwanie semantyczne, podobieństwo danych. |
| rowversion | Unikalna liczba binarna automatycznie zmieniana przy modyfikacji. Przykład: śledzenie zmian, kontrola współbieżności. |
| sql_variant | Może przechowywać wartości różnych typów (np. int, nvarchar). Przykład: tabele tymczasowe, dynamiczne struktury danych. |
| table | Tymczasowa tabela w zmiennej. Przykład: operacje zbiorowe w procedurach i funkcjach. |
| uniqueidentifier | Przechowuje identyfikator GUID (globalnie unikalny). Przykład: klucze główne, identyfikatory replikacji. |
| xml | Przechowuje dane w formacie XML, z opcjonalną walidacją schematu. Przykład: konfiguracje, dane z systemów zewnętrznych, importy danych. |
W starszych wersjach SQL Server dane JSON przechowuje się jako nvarchar.
Łączenie wyrażeń różnych typów w MS SQL Server
W zapytaniach SQL czasami potrzebujemy połączyć dane z kolumn różnego typu np. tekst z liczbą, liczbę z datą, varchar z nvarchar czy int z float. SQL Server w takich przypadkach próbuje automatycznie dopasować typy danych, wykonując tzw. konwersję niejawnie (ang. implicit conversion).
Gdy napotka dwa różne typy danych w jednej operacji (np. dodawanie, porównywanie, łączenie tekstu), SQL Server konwertuje jeden z nich na typ, który ma wyższy priorytet według wewnętrznej hierarchii typów danych. Przykładowo, nvarchar ma wyższy priorytet niż varchar, a float wyższy niż int.
Przykłady łączenia typów:
-
łączenie tekstu z liczbą:
SELECT 'Zamówienie nr: ' + CAST(123 AS varchar); -
łączenie varchar z nvarchar
SELECT N'Cena: ' + '99.99';W tym przypadku varchar zostanie automatycznie skonwertowany do nvarchar, ponieważ Unicode ma wyższy priorytet.
-
łączenie daty z tekstem
SELECT 'Aktualna data: ' + CAST(GETDATE() AS varchar);
Automatyczna konwersja może spowolnić zapytania, zwłaszcza w klauzulach WHERE, JOIN, gdyż uniemożliwia użycie indeksów.
W niektórych przypadkach SQL Server może wykonać konwersję, która prowadzi do utraty precyzji (np. float na int).
Porównując nvarchar z varchar, warto pamiętać o różnicy w kodowaniu i potencjalnych problemach z sortowaniem.
Jawna konwersja za pomocą funkcji CAST() lub CONVERT() zwiększa kontrolę nad sposobem zmiany typu. Informacje na temat tych funkcji znajdziesz w naszym artykule SQL Server funkcje CAST, CONVERT, FORMAT.
Priorytety typów danych
Poniżej lista hierarchii typów danych w SQL Server, uporządkowana według priorytetu (precedence) – od typu o najwyższym do typu o najniższym priorytecie:
- user-defined data types (typy definiowane przez użytkownika)
- json
- sql_variant
- xml
- datetimeoffset
- datetime2
- datetime
- smalldatetime
- date
- time
- float
- real
- decimal
- money
- smallmoney
- bigint
- int
- smallint
- tinyint
- bit
- ntext
- text
- image
- timestamp
- uniqueidentifier
- nvarchar (w tym nvarchar(max))
- nchar
- varchar (w tym varchar(max))
- char
- varbinary (w tym varbinary(max))
- binary (lowest)
Typy danych SQL Server tworzone przez użytkownika
W Microsoft SQL Server typy danych tworzone przez użytkownika (ang. user-defined data types, UDT) umożliwiają standaryzację struktury danych w bazie oraz poprawę spójności i czytelności kodu.
Są szczególnie przydatne w dużych projektach, gdzie wiele tabel korzysta z tych samych typów informacji, np. numerów telefonów, identyfikatorów czy oznaczeń statusów. Przykładowo, zamiast wielokrotnie deklarować kolumny typu VARCHAR(11) dla numeru telefonu, można utworzyć własny typ danych
CREATE TYPE Telefon FROM VARCHAR(11);W poleceniu:
CREATE TYPETelefon – tworzymy nowy typ danych o nazwie TelefonFROM VARCHAR(11)– nowy typ będzie oparty na istniejącym typie VARCHAR(11), czyli ciągu tekstowym o maksymalnej długości 11 znaków
Aby zobaczyć utworzony typ w Object Explorer w środowisku SQL Server Management Studio:
-
kliknij prawym przyciskiem myszy na bazę danych, w której typ został utworzony – w naszym przykładzie jest to Northwind i wybierz opcję Refresh (Odśwież)

-
na drzewie obiektów, kliknij kolejno plusy z lewej strony bazy Northwind, następnie Programmability, następnie Types i User-Defined Data Types

Przykład wykorzystania utworzonego przez użytkownika typu w zapytaniu:
CREATE TABLE Klienci ( Id INT PRIMARY KEY, Numer_telefonu Telefon);Jaki jest cel tworzenia typów danych użytkownika?
Celem tworzenia typów danych użytkownika w SQL Server jest zapewnienie większej spójności, czytelności i łatwiejszego zarządzania strukturą danych w bazie.
Dzięki nim:
- możemy zachować spójność danych – zamiast za każdym razem wpisywać VARCHAR(11), możemy użyć np. nazwy typu Telefon. Dzięki temu mamy pewność, że wszędzie tam, gdzie jest numer telefonu, używamy tej samej długości i formatu.
- łatwiej odczytać co typ reprezentuje – Telefon mówi wprost, co dana kolumna przechowuje, zamiast ogólnego VARCHAR(11).
Znasz już teorię dotyczącą typów danych, ale prawdziwa biegłość w SQL przychodzi wraz z praktyką. Jeśli chcesz przećwiczyć tworzenie własnych struktur danych i pisanie zapytań na praktycznych zadaniach, zapraszamy na nasze kursy SQL. To idealne miejsce, aby pod okiem ekspertów zamienić zdobytą wiedzę w konkretne umiejętności.
