One issue with data types is that they don’t usually mix well. Conversion functions make them mix better!
Though there are times when types are automatically (implicitly) converted from one type to another, in other cases, SQL needs more convincing. In these cases, the CAST
and CONVERT
functions come into play.
All the examples for this lesson are based on Microsoft SQL Server Management Studio and the AdventureWorks2012
database. You can get started using these free tools using my Guide Getting Started Using SQL Server.
In a previous post, I’ve talked about data types and their roles in SQL Server. There are several reasons why SQL Server uses data types, among them is to assist with evaluating expressions. But not all data is in the correct data type. In these cases, one or more values must be converted to a common type before a result is determined.
Date is either converted implicitly or explicitly from one type to another. Implicit data type conversion occurs automatically; whereas, explicit data type conversion occurs per your direction using the CAST
and CONVERT
conversion functions.
Implicit conversions are those conversions that occur automatically whenever the CAST
or CONVERT
functions aren’t used. Not all values can be implicitly converted to another data type. The following chart shows what can be implicitly converted for the common data types we’ve previously covered:
Please keep in mind that this chart shows what implicit conversions are possible, it doesn’t guarantee all values from one type will convert to another. For example, the VARCHAR
value ‘The car broke down
’ never makes a good DATETIME
.
An example of an implicit data conversion occurs when we work with percentages and INT
data types.
Implicit Conversion Results
In this case, the Quantity
was first converted to a MONEY datatype
before the TotalCost
was calculated.
You may be wondering why Quantity
was converted to Money
and not StandardCost
to SMALLINT
.
The reason is that order values are implicitly converted from one data type to another is determined by type precedence.
Data type precedence determines the direction or order implicit datatype occur. Here is the order of precedence for the common data types we have previously covered:
DATETIME
(highest) FLOAT
DECIMAL
INT
BIT
NVARCHAR
VARCHAR
(lowest)
Note: With 30 or more supported data types, the official list is longer.
Data types of lower precedence will attempt to convert to one of higher precedence, but not the other way around.
Consider:
SELECT 100 * .5
This statement returns 50.0
. The reason is that .5
is a higher precedence, so SQL converts 100
, which is an INT
type, to the higher precedence. Since converting from 100
to 100.00
is an allowed implicit conversion, it occurs without error.
Now consider:
SELECT 'Today is ' + GETDATE()
The result we’re aiming for is ‘Today is 2015-07-02 08:01:54.932
’ or something similar, yet the statement returns this error:
<span style="color: #ff0000;">Msg 241, Level 16, State 1, Line 1
Conversion failed when converting date and/or time from character string.</span>
You would think this statement would return a result since it seems it would not be difficult to convert the current date and time to a text value, but because DATETIME
has a higher precedence than any textual value, SQL is trying to convert the text to a date.
‘Today is
‘ isn’t a valid date
, SQL doesn’t know where that exists on any calendar, so throws an error.
There are really two factors that take place to determine whether an item can be implicitly converted to a data type:
- Can a value be converted from one data type to another? Implicit conversion isn’t supported for all data types, so understanding whether certain combinations work, is important to understand.
- What is the data type precedence? If the value’s data type is already at a higher precedence, it won’t be implicitly converted to a lower one.
Explicit Type Conversions with CAST AND CONVERT
It isn’t always possible to combine datatype
s together in an expression without causing a server error.
When this occurs, then we need to explicitly convert one of the data types to another to avoid an error.
An example would be when working with dates. Suppose we want to query that returns text regarding employee
birthdays.
If we try to execute the following command, it fails:
SELECT P.FirstName + ' ' + P.LastName,
'Birth Date ' + E.BirthDate
FROM HumanResources.Employee E
INNER JOIN Person.Person P
ON P.BusinessEntityID = E.BusinessEntityID
It returns the error:
<span style="color: #ff0000;">Msg 402, Level 16, State 1, Line 1
The data types varchar and date are incompatible in the add operator</span>.
The problem is the expression:
'Birth Date'+ E.BirthDate
The column BirthDate
data type is DateTime
. Here, we’re mixing text with dates. In order to fix this, we must first convert the DateTime
data type into a text value.
We can use the CAST
statement to convert the BirthDate
into a VARCHAR
value. This statement runs with no errors.
SELECT P.FirstName + ' ' + P.LastName,
'Birth Date ' + CAST(E.BirthDate as VARCHAR)
FROM HumanResources.Employee E
INNER JOIN Person.Person P
ON P.BusinessEntityID = E.BusinessEntityID
There are two commands we can use to do so: CAST
and CONVERT
.
The main difference between CAST
and CONVERT
is that CONVERT
also allows you to define a format for the converted value. This is handy when, for instance, converting DATETIME
values to VARCHAR
. You can convert the date
into a more human readable format. We’ll talk more about this in the following section.
You just saw how we used CAST
to convert a value from one datatype
to another. Let's explore further.
CAST
The CAST
function is used to convert from a value from one data type to another. It is an ANSI SQL-92 compliant function.
The syntax for the function is:
CAST(value as datatype)
where value
is the item you wish to convert, and datatype
is the type you which to convert the value to.
In previous section’s example, CAST(E.BirthDate as VARCHAR)
converted the DATETIME
column BirthDate
to a VARCHAR
text value.
When converting from a DATATYPE
value to VARCHAR
, I don’t usually use CAST
, as I normally want to format the value; however, I do use CAST
when I just need to do conversion. This occurs when I want to:
- Convert a
VARCHAR
or other text value to a numeric or DATETIME
value for calculations. - Need to convert numeric values to the same type, such as when working with
INT
and FLOAT
values.
Consider the example. The production manager would like to reduce on hand inventory quantities by 10%. What are the new amounts?
To start well, use this query:
SELECT I.ProductID,
I.LocationID,
I.Shelf,
I.Bin,
I.Quantity,
I.Quantity * .90 as ReducedQuantity
FROM Production.ProductInventory I
ORDER BY I.ProductID, I.LocationID
You hand these results to the production manager.
Reduced Quantity with Decimal Places
But notice the ReducedQuantity
column. There are decimal places! The production manager complains about this. In an exasperated tone, she mentions to you that it’s obvious we can’t have ½ a bike on stock, so why is report showing them!
What to do? Use CAST
to convert the calculated value back to an integer.
We can use the following query to do so:
SELECT I.ProductID,
I.LocationID,
I.Shelf,
I.Bin,
I.Quantity,
CAST(I.Quantity * .90 as SMALLINT) as ReducedQuantity
FROM Production.ProductInventory I
ORDER BY I.ProductID, I.LocationID
You hand the following result to the manager who deems them acceptable:
Reduced Quantity Results – Eliminate Decimal Values
In this example, I used to cast the quantity to SMALLINT
as the column data type is SMALLINT
, I could have cast it to INT
, but want to keep the types consistent.
CONVERT
The CONVERT
function is used to convert from a value from one data type to another with formatting. It is specific to SQL Server and not an ANSI SQL-92 compliant function.
The syntax for the function is:
CONVERT(datatype, value, style)
where:
datatype
is the type you which to convert the value to value
is the item you wish to convert style
is the format you wish to see converted values stated as
Where the CONVERT
function really shines is when you want to display date or numeric values in text. We’ll focus on converting dates. Once you get the hang of this, then converting numeric values is a cinch.
CONVERT DATETIME TYPES
Consider the following:
SELECT 'Today''s date is ' + CAST(GETDATE() as varchar)
which returns the result:
Today’s date is Jul 4 2015 10:35AM
There are three things to notice:
- I used two single quotes to embed a single quote in the text value. This is called “escaping” the character (see Constants, Transact-SQL). We need to do this so SQL doesn’t think the single quote is signaling the end of the text value.
- The GETDATE() function is used to return the current date.
- The
date
isn’t in the best format for reading.
So how can we fix the format? We can use CONVERT
with a style.
Check out
SELECT 'Today''s date is ' + CONVERT(VARCHAR, GETDATE(), 101)
which returns the result:
Today’s date is 07/04/2015
Much better!
The “101
” in the CONVERT
is the style. There are many more styles are listed on MSDN, but some of the more popular ones to use with dates are:
CONVERT Function DATETIME styles
Note: You’ll notice there are two styles per listing. This is so you have the choice to display dates with or without the century. Single digit styles display the yeas as two digits (yy); whereas, those in the hundreds display years as four digits (yyyy).
Remember the style is optional with convert.
Summary
Both CAST
and CONVERT are used to switch a value from one data type to another. CAST
is ANSI SQL-92 compliant, so is useful when you’re going to write SQL that needs to execute on different DBMS such as Oracle, MySQL, or SQL Server.
CONVERT
is not ANSI SQL-92 compliant. Its advantage is that you can specify styles which aid in formatting converted values. These are handy, especially when working with dates, when converting values to text.
Use CAST
rather than CONVERT
if you want Transact-SQL program code to comply with SQL-92. Use CONVERT
rather than CAST
to take advantage of the style functionality in CONVERT
.
The post Introduction to SQL Server’s Built-In Conversion Functions appeared first on Essential SQL.