Arithmetic overflow error converting expression to

2019-04-27 19:43发布

问题:

This select statement gives me the arithmetic error message:

SELECT CAST(FLOOR((CAST(LeftDate AS DECIMAL(12,5)))) AS DATETIME), LeftDate 
FROM Table
WHERE LeftDate > '2008-12-31'

While this one works:

SELECT CAST(FLOOR((CAST(LeftDate AS DECIMAL(12,5)))) AS DATETIME), LeftDate 
FROM Table
WHERE LeftDate < '2008-12-31'

Could there be something wrong with the data (I've checked for null values, and there are none)?

回答1:

Found the problem to be when a date was set to 9999-12-31, probably to big for the decimal to handle. Changed from decimal to float, and every thing is working like a charm.



回答2:

In general, converting a date to a numeric or string, to perform date operations on it, is highly inefficient. (The conversions are relatively intensive, as are string manipulations.) It is much better to stick to just date functions.

The example you give is (I believe) to strip away the time part of the DateTime, the following does that without the overhead of conversions...

DATEADD(DAY, DATEDIFF(DAY, 0, <mydate>), 0)

This should also avoid arithmentic overflows...



回答3:

Maybe this helps someone since my problem was a bit different.

The SELECT that was throwing this error had many nested SELECTs and many date comparisons with arithmetic operations like GETDATE() - CloseDate.

The result of such operations was then being compared to '1900-01-01' again mentioned many times in the nested SELECTs.

My solution was to declare variables for result of GETDATE() and datetime variable for '1900-01-01' to avoid conversions.

Declare @CurrentDate datetime = GetDate()
Declare @BlankDate datetime = '1900-01-01'
...
... @CurrentDate - CloseDate ...
... CloseDate <> @BlankDate ...

The DATEADD(DAY, DATEDIFF(DAY, 0, <mydate>), 0) bit from MatBailie's answer was also helpful.