Data Types
SQL Server (also known as MS SQL or t-SQL) supports several data types, from rather standard ones (e.g. INT
, CHAR
), to others that are more complex (e.g. TABLE
, HIERARCHYID
).
Approximate Numerics
FLOAT
This data type is composed of a number that is not an integer, that is: it includes a fraction represented in decimal format. One of the main differences between FLOAT
s and INTEGER
s is that this data type has more precision. It is defined as FLOAT[(n)]
, where n
is the number of bits that are used to store the manitssa, with n<25
as single precission, and n≥25
as double precission.
SELECT
CAST(3.141592653589793238 as FLOAT) float;
About
−1.79E+308
to 1.79E+308
15
digitPractical Tips
REAL
(it only takes 4 bytes), provided the loss accuracy is ok.FLOAT
values are truncated when converted into any type of INTEGER
.FLOAT
equality checks (=), inequality (<>) checks etc, rounding of numbers, etc. FLOAT
s in application like financial applications where accuracy is important.FLOAT
to character types, it is better to use the STR
function instead of CAST
, for it allows better control on the format.REAL
This data type is used for floating-point values, like FLOAT
. However, REAL
is a single precision floating point number, whereas FLOAT
is a double precision floating point number. In short, if you double the precision, you double the bits of memory. REAL
is equivalent to FLOAT(24)
.
SELECT
CAST(3.141592653589793238 as REAL) real;
About
−3.40E+38
to -1.18E-38
for negative values, and 1.18E-38
to 3.40E+38
for positive values. The value 0
can also be stored. 7
digit4
bytesPractical Tips
FLOAT
.REAL
is less precise than FLOAT
- but if precision is your concern, you should use Exact Numerics (DECIMAL
is the safe choice).REAL
to character types, it is better to use the STR
function instead of CAST
, for it allows better control on the format.Exact Numerics
TINYINT
, SMALLINT
, INT
& BIGINT
These data types represent integer values. The main difference between them is the amount of bites they can be stored in.
SELECT
CAST (13 as TINYINT) tinyint,
CAST (32000 as SMALLINT) smallint,
CAST (356742 as INT) int,
CAST(-70000000000 as BIGINT) bigint;
About:
TINYINT
:
0
to 255
1
byteSMALLINT
:
−32,768
to 32,768
2
bytesINT
:
-2,147,483,648
to 2,147, 483,648
4
bytesBIGINT
:
−9,223,372,036,854,775,808
to 9,223,372,036,854,775,808
8
bytesPractical Tips:
INTEGER
s are converted to character types, if the value is too big to fit into a the latter, t-SQL adds an asterisk *
to indicate so. INTEGER
s larger than 2,147,483,647 are converted by default into DECIMAL
instead of BIGINT
- unless explicitly specified via CAST
.+
, -
, *
, /
, or %
) to make implicit or explicit conversions from INT
, SMALLINT
, TINYINT
, or BIGINT
to FLOAT
, REAL
, DECIMAL
, or NUMERIC
, the rules applied by SQL Server to calculate the data type and precision of the results depends on whether the query includes automatic parameters:- If a query does not have automatic parameters, the value is first converted into
NUMERIC(p,0)
. - If a query includes automatic parameters, the value is always converted into
NUMERIC(10,0)
before being converted to the final data type.
/
. Automatic opperators may affect not only the precision, but also the value.NUMERIC
& DECIMAL
These data types are used to store numbers that have fixed precision and scale.
De facto,NUMERIC
andDECIMAL
are used as synonyms. However, whileNUMERIC
determines the exact precision and scale,DECIMAL
specifies only the exact scale, the precision being equal or greater than what the coder specifies). This specification is given byp
ands
: that is,NUMERIC(p,[s])
andDECIMAL(p,[s])
.DEC
is the short forDECIMAL
, andNUM
forNUMERIC
.
SELECT
CAST (21.054 as NUMERIC(10,1)) numeric, CAST (21.054 as DECIMAL(10,3)) decimal;
About:
-10E38
to 10E38
5
to 17
bytesPractical Tips:
NUMERIC
and DECIMAL
can be used interchangeably.DECIMAL(3,1)
and DECIMAL(3,0)
considered different.NUMERIC(5,3)
. DECIMAL
or NUMERIC
to FLOAT
or REAL
can entail a loss of precision. INT
, SMALLINT
, TINYINT
, FLOAT
, REAL
, MONEY
or SMALLMONEY
to DECIMAL
or NUMERIC
can entail an overflow. DECIMAL
or NUMERIC
with a lower precision and scale. SET ARITHABORT
is ON
, SQL Server flags an error if an overflow occurs. MONEY
& SMALLMONEY
These data types are used to represent monetary values. MONEY
values correspond to 8-byte DECIMAL
values, rounded up to 4 decimals after the point. SMALLMONEY
corresponds to MONEY
, but it is stored in 4 bytes.
SELECT
CAST (197240.23 as SMALLMONEY) smallmoney,
CAST (120134665234543.23 as MONEY) money;
MONEY and SMALLMONEY are good data types to display results o
About:
MONEY
:
Range: −922,337, 203, 685,477.5808
to +922,337, 203, 685,477.5807
Memory: 8
bytes
SMALLMONEY
:
Range: −214,478.3648
to +214,478.3647
Memory: 4
bytes
Practical Tips:
.
to separate partial currency units , e.g. 7.53 can specify 7 dollars and 53 cents.MONEY
and SMALLMONEY
are good data types to display results to the user, but they are not recommended for calculations due to their lack of accuracy and intrinsic inflexibility.DECIMAL
is the recommended data type in order to store and work with currencies. MONEY
and SMALLMONEY
rounds up the values, and thus the results may be affected by errors accumulating over time.'
. In fact, note that SQL Server cannot store any information regarding the currency symbol - it merely stores the numeric value.FORMAT()
, specifying the accuracy ('Cn'
where n
is an integer that represents the decimal part) and the culture argument for the currency - you can learn more about this here. select
FORMAT((select smallmoney FROM f), 'C4', 'ja-JP') Yen,
FORMAT(CAST(1498.24 as smallmoney), 'C2', 'de-de') euro;
Character Data Types
CHAR
& VARCHAR
CHAR[(n)]
represents a fixed-length string of single-byte characters, where n
is the length of the string in bytes. It can also be written as CHARACTER(n)
.
VARCHAR[(n)]
describes a variable-length string of single-byte characters. In opposition to CHAR
, the values in this data type are stored in their actual length.
SELECT
CAST (142 as CHAR(3)) char, CAST('character' as char(3)) char2;
SELECT
CAST (56125 as VARCHAR) varchar, CAST ('username' as varchar) varchar2;
About:
CHAR
0
to 8000
charsn
bytesVARCHAR
0
to 8000
charsn
bytes +2
Practical Tips:
CHAR(n)
and VARCHAR(n)
, if n
is omitted the length of the string is assumed to be 1.n
is smaller than the length of characters inside the string, it will be truncated (as in the second example above).n
bytes, and the number of characters that can be stored is n
as well. n
but the number of characters that can be stored is smaller.n
is not specified, its default value when using the functions CAST
and CONVERT
is 30.CHAR
or VARCHAR
are assigned the default collation of the database, unless a specific collation is assigned via the function COLLATE
.CHAR
when the size of the column data entries are consistent.VARCHAR
when the size of the column data entries vary considerably. VARCHAR(max)
when the size of the column data entries vary considerably and the length of any given string can be greater than 8000 bytes.VARCHAR(15)
to CHAR(5)
, or CHAR(10)
to CHAR(5)
, the collation of the input value is assigned to the converted value.E+/-
and a number.+
/ -
). note, however, that leading blanks are ignored, and that comma separators - such as the thousands separator - are not allowed in the string.MONEY
or SMALLMONEY
data types can include an optional decimal point and dollar sign $
. Comma separators are allowed. INT
, its value becomes 0
. DATE
, its value becomes the default value for date - i.e. 1900-01-01
.NCHAR
& NVARCHAR
NCHAR[(n)]
stores fixed-length strings of Unicode characters. The main difference with CHAR
is that each character of the NCHAR
data type is stored in 2 bytes. Thus, the maximmum number of characters in a column in NCHAR
is 4000
.
NVARCHAR[(n)]
stores variable-length strings of Unicode characters. The difference between NVARCHAR
and VARCHAR
is exactly the same as with CHAR
and NCHAR
: NVARCHAR
takes two bytes of storage per character, whereas VARCHAR
only takes one.
SELECT
CAST (25515 as NCHAR) nchar;
SELECT
CAST (446173 as NVARCHAR) nvarchar;
About:
NCHAR
0
to 4000
chars2*n
bytesNVARCHAR
0
to 4000
chars2*n
bytes + 2
bytesPractical Tips:
NCHAR(n)
and NVARCHAR(n)
, if n
is omitted the length of the string is assumed to be 1.CAST
function, it takes the default value of 30.NCHAR
when the size of the column data entries are consistent.NVARCHAR
when the size of the column data entries vary considerably.NVARCHAR(max)
when the size of the column data entries vary considerably and the length of any given string can be greater than 4000 byte-pairs.NCAHR(n)
and NVARCHAR(n)
, the n does not define the number of characters, but the string length in byte-pairs.NCHAR
and NVARCHAR
values to other data types, see the discussion regarding CHAR and VARCHAR
data types.Temporal Data Types
DATETIME
& SMALLDATETIME
DATETIME
is used to specify a date and a time - plain and simple! - with each one of these values being stored separately as integers in 4 bytes. The time part has a precision of three-hundredths of a second. In contrast, SMALLDATETIME
stores each value in 2 bytes and has a precision of minutes.
SELECT
CAST('10-12-1815 13:24:45' AS DATETIME) datetime,
CAST('10-12-1915 13:24:45' AS SMALLDATETIME) smalldatetime,
CAST('13:24:45' AS DATETIME) no_date_time,
CAST('10-12-1815' AS DATETIME) no_time_date;
About:
DATETIME
: 1753-01-01 00:00:00 to 9999-12-31 23:59:59.999
SMALLDATETIME
: 1900-01-01 00:00:00 to 2079-06-06 23:59:59
DATETIME
: YYYY-[M]M-[D]D[( |T)[H]H:[M]M:[S]S[.DDDDDD]]
SMALLDATETIME
: YYYY-[M]M-[D]D[( |T)[H]H:[M]M:[S]S]
SMALLDATETIME
only)Practical Tips:
DATETIME
are rounded to increments of .000
, .003
, or .007
seconds.DATE
value to DATETIME
or SMALLDATETIME
, the date part is copied and the time part is set to 00:00:00.000.TIME
value to DATETIME
, the date part is set to 01/01/1900 and the time part is copied. For SMALLDATETIME
, the fractional seconds are set to 0.TIME
is greater than three digits, DATETIME
truncates it.SMALLDATETIME
value to DATETIME
, the seconds and fractional seconds are set to 0.DATETIMEOFFSET
to DATETIME
or SMALLDATETIME
, date and time components are copied, but the time zone is truncated. For DATETIME
, if the fractional precision of the original value is greater than three digits it is truncated. For SMALLDATETIME
, fractional seconds are set to 0.DATE
& TIME
To store the DATE
or TIME
separately, DATETIME
is rather inconvenient. Thus, you can use any one of these data types to store each value separately.
select
CAST ('12-06-1934' AS DATE) date, CAST ('12:34:15:003' AS TIME) time;
About:
DATE:
01/01/0001
to 12/31/9999
1
day3
bytesTIME:
00:00:00.0000000
to 23:59:59.9999999
100
nanoseconds3
to 5
bytesPractical Tips:
DATE
:
DATE
values can be specified by four, six, or eight digits. SET LANGUAGE
and SET DATEFORMAT
./
, hyphens -
, or periods .
.Acceptable formats for DATE
are:
- [m]m/dd/[yy]yy
- [m]m-dd-[yy]yy
- [m]m.dd.[yy]yy
- mm/[yy]yy/dd
- mm-[yy]yy/dd
- [m]m.[yy]yy.dd
- dd/[m]m/[yy]yy
- dd-[m]m-[yy]yy
- dd.[m]m.[yy]yy
- dd/[yy]yy/[m]m
- dd-[yy]yy-[m]m
- dd.[yy]yy.[m]m
- [yy]yy/[m]m/dd
- [yy]yy-[m]m-dd
- [yy]yy-[m]m-dd
DATE
.TIME
:
:
, or a period .
. - A single digit means tenths-of-a-second
- Two digits mean hundredths-of-a-second
- Three digits mean thousandths-of-a-second.
Acceptable formats for TIME
are:
DATETIME2
This data type stores high precission date and time data. It can also be defined for variable lengths depending on the requirement.
SELECT
CAST ('10-12-1815 13:24:45.04415' AS DATETIME2) datetime2;
About:
01/01/0001
to 12/31/9999
100
nanoseconds6
to 8
bytesPractical Tips:
DATETIME2
value is CAST
to a VARBINARY
value, an additional byte is added to the VARBINARY
value to store precision.DATETIME
to DATETIME2
data types show improved accuracy by accounting for the fractional milliseconds, resulting in different converted values.DATETIME2
datatype whenever a mixed comparison scenario between DATETIME
and DATETIME2
datatypes exists.DATE
and TIME
types are permitted if all parts of the strings are in valid formats. Otherwise, a runtime error is raised.DATETIMEOFFSET
This data type, in contrast with all the types discussed before, captures the time zone offset portion. Besides the memory space needed, it has the same properties as DATETIME2
.
SELECT
CAST ('10-12-1815 13:24:45 -02:30' AS DATETIMEOFFSET) datetimeoffset;
About:
01/01/0001
to 12/31/9999
100
nanoseconds10
bytes (default)Practical Tips:
DATETIMEOFFSET
provides time zone compatibility for those applications implemenbted globally. TIME
or DATETIME
value. +
and -
are the indicate whether the time zone offset is added or subtracted from the UTC time to obtain the local time. Including them is obligatory.Binary Strings
BINARY
& VARBINARY
These data types allow storing binary values. BINARY
works best when the values of the column data entries are consistent, with the length of such values ranging from 1 to 8000 bytes. On the contrary, VARBINARY
allows considerable variations between different values in the data. They store bit strings, represented in the internal format of the system. Therefore, they are entered using hexadecimal numbers.
SELECT
CAST(20 AS BINARY(5)) binary1, CAST(34516 AS VARBINARY(5)) varbinary ;
About:
0
to 8000
bytesBINARY
and the actual length of the data entered +2
bytes for VARBINARY
Properties:
n
isn't specified.n
isn't specified via CAST
.VARBINARY(MAX)
.CAST
or CONVERT
functions - implicit conversion is not allowed.BINARY
or VARBINARY
data types of unequal length, SQL Server truncates the data on the right. This happens with CHAR
, VARCHAR
, NCHAR
, NVARCHAR
, BINARY
, VARBINARY
, TEXT
, NTEXT
, and IMAGE
.BINARY
or VARBINARY
is recommended if binary data is the best way to move it. However, make sure the binary type has a large enough size, and to convert it back to the original data type in the same version of SQL Server.BINARY
or VARBINARY
. However, if you convert it back, the value will differ if truncation has occurred. BIT
This is a data is used for specifying the Boolean data type with three possible values: 1
, 0
, and NULL
.
SELECT
CAST (0 as BIT) bit1, CAST (0.4 as BIT) bit2, CAST ('FALSE' as BIT) bit3;
About:
0
or 1
Properties:
BIT
converts any nonzero value to bit 1.TRUE
to 1 and FALSE
to 0BIT
columns, so if a table has 8 or fewer columns, it stores them as 1 byte, from 9 to 19 as 2 bytes, and so on.BIT
values: TRUE is converted to 1 and FALSE is converted to 0.IMAGE
Microsoft recommends using VARBINARY(MAX)
instead of IMAGE
for storing a large amount of data in a single column since IMAGE
will be retired in a future version of MS SQL Server.
Others
TABLE
Is a special data type used to store a result set for processing at a later time. Its use is recommended for temporarily storing a set of rows that are returned as the table-valued function result set. To declare variables of the type TABLE
, use DECLARE @local_ variable as TABLE
Practical Tips:
TABLE
variable behaves like a local variable with a well-defined scope that can be used in the function, stored procedure, or batch in which it's declared.A TABLE
can be used in SELECT
, INSERT
, UPDATE
, and DELETE
statements.TABLE
variables are automatically cleaned up at the end of the function, stored procedure, or batch in which they're defined.TABLE
variables last only for the duration of an update on the TABLE
variable. TABLE
variables isn't supported. ROWVERSION
ROWVERSION
is a data type that conveys automatically generated, unique binary numbers within a database. It is highly recommended to version-stamp table rows.
Practical Tips:
ROWVERSION
tracks the relative time within a database, not the actual time.DATE
or TIME
- to record a date or time use DATETIME2
.ROWVERSION
column. ROWVERSION
column is modified or inserted, the incremented database rowversion value is inserted in the ROWVERSION
column.ROWVERSION
value is incremented with any update statement, even if no row values are changed.TIMESTAMP
is a deprecated synonym for ROWVERSION
.HIERARCHYID
This data type is used to store an entire hierarchy, and it is implemented asa Commin Language Runtime (CLR) user-defined type that comprises several system functions for creating and operating on hierarchy nodes. A value of the HIERARCHYID
data type represents a position in a tree hierarchy
Practical Tips:
HIERARCHYID
encodes information about a single node in a hierarchy tree by encoding the path from the root of the tree to the node.Data Precedence
But what happens if an operator combines two or more expressions containing different data types? In such case, all of the data types with a lower priority are converted into the data type with the higher priority. This is also known as implicit conversion.
The data precedence in SQL Server is the following:
Note that this established priority is also used when optimising indexes of different data types.