Reputation: 97
I have following table and table data. After which when I execute the select statement using cases, then I am getting error
The conversion of a date data type to a datetime data type resulted in an out-of-range value.
But when I comment my second case then select works fine. Please help me to understand this issue
CREATE TABLE TEST (
ID varchar(20),
T_Date date,
FLAG varchar(20)
);
insert into TEST values('1234', '0001-01-01', NULL);
select t.T_Date, t.FLAG,
CASE
WHEN t.FLAG IS NULL AND t.T_Date IS NOT NULL AND t.T_Date != '2001-01-01' THEN t.T_Date
WHEN t.FLAG IS NULL AND (t.T_Date IS NULL OR (t.T_Date IS NOT NULL AND t.T_Date = '2001-01-01')) THEN CONVERT(datetime, '20201216', 112) + 10
END as t_date
FROM TEST t
Upvotes: 0
Views: 639
Reputation: 27225
Because every branch of a case
expression must return the same datatype. So with your convert to datetime
in the second branch you forced SQL Server to try and convert your first branch to datetime
also due to datatype precedence.
And when, in the first branch, you try and convert your date
value, "0001-01-01", to datetime
it fails, because the lowest value datetime
can handle is "January 1, 1753".
You also cannot add 10 to a date
, nor should you, even though datetime
allows it. What are you adding? Days? Hours? Minutes? Use the dateadd
function to correctly add to a date
.
SELECT t.T_Date, t.FLAG,
CASE
WHEN t.FLAG IS NULL AND t.T_Date IS NOT NULL AND t.T_Date != '2001-01-01' THEN t.T_Date
WHEN t.FLAG IS NULL AND (t.T_Date IS NULL OR (t.T_Date IS NOT NULL AND t.T_Date = '2001-01-01')) THEN DATEADD(DAY, 10, CONVERT(DATE, '20201216', 112))
END AS t_date
FROM #TEST t
Upvotes: 0
Reputation: 239664
A CASE
expression has to produce a value of one fixed type, no matter which clause ends up matching.
datetime
has a higher precedence than date
, and is therefore the type of your CASE
expression.
A datetime
is incapable of storing a date before 1753. Your date
value is in the year 1.
As suggested (for at least a decade):
Use the
time
,date
,datetime2
anddatetimeoffset
data types for new work.
select t.T_Date, t.FLAG,
CASE
WHEN t.FLAG IS NULL AND t.T_Date IS NOT NULL AND t.T_Date != '2001-01-01'
THEN t.T_Date
WHEN t.FLAG IS NULL AND (t.T_Date IS NULL OR (t.T_Date IS NOT NULL AND t.T_Date = '2001-01-01'))
THEN CONVERT(date, '20201226', 112)
END as t_date
FROM TEST t
Upvotes: 1