Useful SQL Server functions: TRY_CAST & TRY_CONVERT
September 09, 2020
You've probably used the CAST
and CONVERT
functions to switch between data types, but did you know there's a couple of handy counterparts to these? The TRY_CAST
and TRY_CONVERT
functions.
This post will look at these two functions, how to use them, and what makes them useful.
TRY_CAST & TRY_CONVERT
TRY_CAST
& TRY_CONVERT
follow the same syntax as CAST
and CONVERT
but with one key difference: TRY_CAST
and TRY_CONVERT
return NULL
if the conversion fails.
The functions are laid out like this:
TRY_CAST
TRY_CAST (column_or_value AS data_type)
TRY_CONVERT
TRY_CONVERT (data_type, column_or_value, optional_style)
Let's look at a couple of simple examples.
SELECT
TRY_CAST('42' AS INTEGER) as result
,TRY_CAST('42' AS INTEGER) * TRY_CAST('42' AS INTEGER) as result_sq
SELECT
TRY_CAST('To be, or not to be' AS DATE) as result
Notice when the conversion failed, the column has a NULL
value, and the query successfully ran.
There is one catch to be aware of, however. TRY_CAST
and TRY_CONVERT
will still error if the conversion is not permitted.
This example returns an error because an INTEGER
to DATE
conversion is not allowed.
SELECT
TRY_CAST(42 AS DATE) as result
For more details on permitted conversions, see the table here.
Why is this useful?
Firstly because it won't break a query if conversion fails (some exceptions, see above), the returned value will be NULL
instead of an error.
Secondly, TRY_CAST
and TRY_CONVERT
are useful because they allow you to try alternatives if conversion fails.
When used in a CASE
statement, this lets you test if a conversion is possible and respond if not. You can keep trying other conversions until you've exhausted all options and return NULL
.
An example
Let's pretend for a moment that the data in this example represents a table of imported Microsoft Excel data. We need to convert the messy_date
column, a VARCHAR
, to a DATE
, but (typically) it's full of mixed formats.
We can use TRY_CONVERT
and TRY_CAST
here to test three different conversions and then return NULL
.
-- Setup example data
DROP TABLE IF EXISTS #excel_data
CREATE TABLE #excel_data (
messy_date VARCHAR(100)
)
INSERT INTO #excel_data(messy_date)
VALUES
('30/08/2020')
,('02/25/2020')
,('44081')
,(NULL)
,('#N/A')
DECLARE @excel_serial_start DATE = '1900-01-01'
SELECT
CASE
WHEN TRY_CONVERT(DATE, #excel_data.messy_date, 103) IS NOT NULL THEN
CONVERT(DATE, #excel_data.messy_date, 103)
WHEN TRY_CONVERT(DATE, #excel_data.messy_date, 101) IS NOT NULL THEN
CONVERT(DATE, #excel_data.messy_date, 101)
WHEN TRY_CAST(#excel_data.messy_date AS INT) IS NOT NULL THEN
DATEADD(DAY, CAST(#excel_data.messy_date AS INT), @excel_serial_start)
ELSE
NULL
END as result
FROM
#excel_data
First, we test for the British date format (103). If that fails, we try the US date format (101).
Our example data includes dates represented as the Excel serial number. To handle this, we test if we can convert it to an INTEGER
and if we can use the DATEADD
function to return the date. If all of these are unsuccessful, then we return NULL
.
Pretty handy, right? We've managed to convert three different date formats without using convoluted string manipulation.
Conclusion
In this article, we've taken a look at two useful SQL Server conversion functions, TRY_CAST
and TRY_CONVERT
.
Next time you've got any messy Data Type conversions, give TRY_CAST
or TRY_CONVERT
a try (pun intended).