Working on universal applications has its own challenges. Often I have seen developers resort to unwanted conversions inside the database based on application needs. I am a firm supporter that databases are not the place to play with date and time conversions. Databases are a great source for storing and retrieving data based on your needs. It has to be treated like this for most parts.
In this blog post, let’s review some of the common errors that are often encountered when working with datetime datatypes. Though there are a number of errors that we can get with datetime, we will look at the basic mistakes that most make in this blog.
World of Implicit Conversions
A lot of times developers resort to using VARCHAR as the default datatype for storing datetime values. The argument I get is – “I am not sure what format the date will be sent by the user, hence I want to capture the values as-is.” While this is a valid argument, it is not the right argument. Let’s review the below sample:
CREATE TABLE #emp_data
( emp_id INT,
emp_name VARCHAR(100),
dob VARCHAR(12)
)
INSERT INTO #emp_data
SELECT 10, 'Adam', '07/19/1971' UNION ALL
SELECT 20, 'Pinal', '04/11/1978' UNION ALL
SELECT 30, 'Peter', '22/21/1200'
In the above example, we have created a table with 3 values. As you can see, the dob for “Peter” has been entered incorrectly. If you query the table as is without any date function, it would work perfectly fine.
select emp_name, dob from #emp_data
order by dob
The output looks like:
Let us next use a datetime function and see what the output would look like. Since I am not sure which of these is the month column, we will try to extract the month from each of the rows using the following TSQL.
SELECT emp_name, MONTH(dob) as Month_name
FROM #emp_data
The output is an error which looks like:
emp_name Month_name
—————————————— ———–
Adam 7
Pinal 4
Msg 241, Level 16, State 1, Line 17
Conversion failed when converting date and/or time from character string.
As guessed, the column value that has “Peter” resulted in an error.
Lesson learned: Don’t try to use VARCHAR datatype to store DATETIME values.
In this context, keep a close eye on the execution plans for such mismatch. In the above query we will be shown a “Warning” with details which is not tough to miss. The execution plan looks like:
Note the CONVERT_IMPLICIT option in the execution plans and the yellow warning sign as part of execution plan. These are outcome of datatype mismatch.
Know your regional settings
Different countries have different settings or default values when working with dates. Some use MM/DD/YYYY, others use DD/MM/YY and a number of such combinations can be achieved. When working with datetime datatypes, know what your server settings are. To illustrate this, I will be using the below TSQL:
— What is the output here?
DECLARE @regional_test table(dob datetime)
INSERT INTO @regional_test SELECT '25/07/2014'
SELECT dob, month(dob) as month_value from @regional_test
On executing this, we will get an error as mentioned below:
Msg 242, Level 16, State 3, Line 7
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
The statement has been terminated.
dob month_value
———————– ———–
(0 row(s) affected)
To know what regional settings are on SQL Server, use the following command:
DBCC USEROPTIONS
The output shows the setting that is on the server. In our example it is mdy. I am showing a partial output from the above query.
Lesson learned: When working with datetime, know your regional settings and do not use ambiguous formats to store date values.
Conclusion
In this article, we saw two of the most common mistakes made when using datetime datatypes inside SQL Server. The application owner owns the datetime format for storage inside the database. The front end shows this data in any format once we standardize it in the backend. Hopefully you will not get these errors in the future and will explore more into the world of datatime datatypes.
Next Steps
Learn more about Embarcadero Rapid SQL, the intelligent IDE for SQL development, and try Rapid SQL for free.