Tables, rows, columns and data types
Every column has a data type that decides what it can hold, how much space it takes and what goes wrong at the edges. Learn the types you will use every day and how to choose between them.
date column hold the word “soon”, or a tinyint hold 300.
SELECT COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH AS MaxLength, NUMERIC_PRECISION AS [Precision], NUMERIC_SCALE AS Scale, IS_NULLABLEFROM INFORMATION_SCHEMA.COLUMNSWHERE TABLE_NAME = 'Products'ORDER BY ORDINAL_POSITION;COLUMN_NAME DATA_TYPE MaxLength Precision Scale IS_NULLABLE ----------- --------- --------- --------- ----- ----------- ProductId int NULL 10 0 NO Name nvarchar 60 NULL NULL NO CategoryId int NULL 10 0 YES Price decimal NULL 10 2 NO Stock int NULL 10 0 NO Unit nvarchar 10 NULL NULL NO AddedOn date NULL NULL NULL NO
The types you will use most
| Type | Holds | Size | Use it for |
|---|---|---|---|
int | |||
bigint / smallint / tinyint | |||
decimal(p, s) | |||
float | |||
bit | |||
nvarchar(n) | |||
varchar(n) | Shipped | ||
char(n) / nchar(n) | GB | ||
date | |||
datetime2(p) | datetime) | ||
datetimeoffset | |||
uniqueidentifier |
Text: varchar or nvarchar?
varchar stores one byte per character from a single code page (on most servers, Western European). Characters outside it are replaced, without any error. nvarchar stores Unicode, so it can hold any language. A text literal needs an N in front (N'…') to be Unicode too:
SELECT 'Łódź' AS WithoutN, N'Łódź' AS WithN, LEN(N'Łódź') AS Characters, DATALENGTH(N'Łódź') AS Bytes;WithoutN WithN Characters Bytes -------- ----- ---------- ----- Lódz Łódź 4 8
N, the literal is varchar, and Ł and ź are swapped for the nearest Latin letters as soon as the literal is read, before it is used anywhere. LEN counts characters; DATALENGTH counts bytes, two per character for nvarchar.
Numbers: exact or approximate?
decimal stores numbers exactly, digit by digit. float stores the nearest binary fraction, which is fast and has a huge range but cannot hold 0.1 exactly, just as 1/3 cannot be written exactly in decimal.
SELECT IIF(CAST(0.1 AS float) + CAST(0.2 AS float) = 0.3, 'equal', 'not equal') AS FloatTest, IIF(CAST(0.1 AS decimal(10,2)) + CAST(0.2 AS decimal(10,2)) = 0.3, 'equal', 'not equal') AS DecimalTest;FloatTest DecimalTest --------- ----------- not equal equal
IIF(test, a, b) returns a when the test is true and b otherwise; you will meet it properly in the Functions module. With float, 0.1 + 0.2 comes out a hair above 0.3, so the test fails. That is why prices in BuildMart are decimal(10,2): up to 10 digits, 2 of them after the point.
int cuts off the fraction instead of rounding, and dividing one int by another gives an int:
SELECT CAST(12.7 AS int) AS CutOff, 7 / 2 AS IntDivision, 7 / 2.0 AS DecimalDivision;CutOff IntDivision DecimalDivision
------ ----------- ---------------
12 3 3.500000Dates
date or datetime2 columns, never as text: only real date columns sort correctly, reject 30 February, and work with date functions. Write date literals as 'yyyy-mm-dd' or 'yyyymmdd'. Other formats such as '03/04/2024' mean different days depending on the server’s language settings.
SELECT CAST('2024-02-29' AS date) AS LeapDay, CAST('20241231' AS date) AS NewYearsEve, CAST('2024-06-12 14:30:00' AS datetime2(0)) AS Delivery;LeapDay NewYearsEve Delivery ---------- ----------- ------------------- 2024-02-29 2024-12-31 2024-06-12 14:30:00
INFORMATION_SCHEMA.COLUMNS, list each column of the Customers table with its name, data type, maximum length and whether it allows NULL, in table order.
Show a hint
Show the solution
SELECT COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH AS MaxLength, IS_NULLABLEFROM INFORMATION_SCHEMA.COLUMNSWHERE TABLE_NAME = 'Customers'ORDER BY ORDINAL_POSITION;COLUMN_NAME DATA_TYPE MaxLength IS_NULLABLE ----------- --------- --------- ----------- CustomerId int NULL NO FirstName nvarchar 40 NO LastName nvarchar 40 NO City nvarchar 40 YES Email nvarchar 100 YES Phone varchar 20 YES JoinedOn date NULL NO
Remember
Every column has a name, a type and a NULL rule; the type decides what values are allowed. Use intfor whole numbers,decimal(p, s)for money and measurements,floatonly for approximate science or geometry.Use nvarchar(andN'…'literals) for text people type;varcharsilently changes characters outside its code page.Converting to intcuts off the fraction, andint / intis anint: 7 / 2 = 3.Store dates in dateordatetime2, and write literals as'yyyy-mm-dd'.