我试图将数字(16,8)添加到smalldatetime。我收到一个我无法理解的溢出错误。
metric_value是数字,business_date是smalldatetime。
SELECT
rsda.name
, business_date
, metric_value
, DATEADD(dd, metric_value, business_date) AS o_dt
, metric.name
FROM [redacted] met
INNER JOIN [redacted] rsda ON met.bu_id = rsda.data_accessor_id
INNER JOIN Metric ON met.metric_id = metric.metric_id
WHERE CHARINDEX('Remodel', metric.name) > 0
Msg 517, Level 16, State 2, Line 1
Adding a value to a 'smalldatetime' column caused an overflow.
我意识到明显的答案是"你的一个日期超过了9999年和#34;但这不是这种情况。所有日期都在2017年,并且所有数字都是100以下的整数,至少在WHERE子句为真时。
会议桌上有很多其他不相关的数据给我的改造'标准,我想知道这是否会导致错误。这是一张奇怪的桌子,但我无法控制它的设计。是否有可能在应用我的WHERE子句之前发生了部分DATEADD进程?我无法想象还有什么。
修改即可。当我删除DATEADD字段时:
这是' ORDER BY business_date ASC'
的第一行+----------+---------------------+--------------+-------------+
| name | business_date | metric_value | name |
+----------+---------------------+--------------+-------------+
| 466 - 94 | 2017-03-13 00:00:00 | 59.00000000 | FullRemodel |
+----------+---------------------+--------------+-------------+
ORDER BY business_date DESC
+----------+---------------------+-------------+-------------+
| 440 - 87 | 2017-07-31 00:00:00 | 38.00000000 | FullRemodel |
+----------+---------------------+-------------+-------------+
ORDER BY metric_value ASC
+----------+---------------------+------------+----------------+
| 471 - 05 | 2017-05-01 00:00:00 | 0.00000000 | PartialRemodel |
+----------+---------------------+------------+----------------+
ORDER BY metric_value DESC
+----------+---------------------+-------------+-------------+
| 466 - 86 | 2017-03-13 00:00:00 | 59.00000000 | FullRemodel |
+----------+---------------------+-------------+-------------+
答案 0 :(得分:0)
是否有可能在应用我的WHERE子句之前发生了部分DATEADD进程?
是。计算表达式的计算标量可以在行被过滤之前在行上运行。有关此主题的一些链接位于my answer here。
如果两个输入将导致smalldatetime范围的有效日期,则可以使用CASE
表达式仅执行dateadd。
CASE
WHEN metric_value BETWEEN datediff(day, business_date, '1900-01-01')
AND datediff(day, business_date, '2079-06-06')
THEN
DATEADD(day, metric_value, business_date)
END
答案 1 :(得分:0)
或者您也可以使用(在SELECT中)
CASE
WHEN metric_value <= datediff(day, GETDATE(), '20790606')
THEN DATEADD(day, metric_value, business_date)
ELSE NULL
END AS o_dt
在日期时间使用BETWEEN会变得很小,所以我尽量避免使用它。
编辑:根据马丁的评论,我不再认为这是一个有效的解决方案。
结合@Martin Smith的回答,你也可以改变你的想法 查询子查询,它应该过滤掉那些行 导致错误。
SELECT t1.rsda_name , t1.business_date , t1.metric_value , DATEADD(day, t1.metric_value, t1.business_date) AS o_dt , t1.metric_name FROM ( SELECT rsda.name AS rsda_name , business_date , metric_value , metric.name AS metric_name FROM [redacted] met INNER JOIN [redacted] rsda ON met.bu_id = rsda.data_accessor_id INNER JOIN Metric ON met.metric_id = metric.metric_id WHERE CHARINDEX('Remodel', metric.name) > 0 ) t1
答案 2 :(得分:-1)
你需要在DATEADD()函数中用DAY替换'dd'。