ern*_*est 0 sql t-sql sql-server sql-server-2008
这是我正在使用的代码:
SELECT SalesItemPK
,FieldName
,Value /*Convert date to the first of the selected month*/
FROM [Oasis].[dbo].[vw_SALES_SalesItemDetails]
WHERE SalesItemPK IN(
1425
,1225
,1556
,1589
,1599
,1588
,1590)
AND FieldName = 'Estimated Ship Date'
AND CONVERT(DATETIME, Value) >= CONVERT(DATETIME, '1/1/2010')
Run Code Online (Sandbox Code Playgroud)
(我只选择那些PK,因为这些是查询中的所有行.)
这是我收到的错误:
将varchar数据类型转换为日期时间数据类型会导致超出范围的值
以下是从我的视图返回的数据示例.最终的解决方案实际上将值转换为各自月份的第一个.但无论如何都会抛出错误.

当我删除WHERE时,它工作正常.所以有一些奇怪的事情到目前为止我似乎无法弄明白.有任何想法吗?
赔率是,日期被解释为d/m/y(并且第一行因为没有第18个月而失败),或者你有一段数据,其中第一部分(月)> 12.
要查找有问题的行:
SELECT Value FROM [Oasis].[dbo].[vw_SALES_SalesItemDetails]
WHERE SalesItemPK IN (1425,1225,1556,1589,1599,1588,1590)
AND ISDATE(Value) = 0;
Run Code Online (Sandbox Code Playgroud)
(如果你发现有问题的行,显然要修复它们.)
您还可以使用以下方法确保将值解释为m/d/y(并且不会因列中的其他垃圾而失败):
SELECT SalesItemPK, FieldName, Value,
FirstOfMonth = CASE WHEN ISDATE(Value) = 1 THEN
DATEADD(DAY,1-DAY(CONVERT(DATETIME,Value,101)),CONVERT(DATETIME,Value,101)) END
FROM [Oasis].[dbo].[vw_SALES_SalesItemDetails]
WHERE SalesItemPK IN (1425,1225,1556,1589,1599,1588,1590)
AND FieldName = 'Estimated Ship Date'
AND CASE WHEN ISDATE(Value) = 1 THEN CONVERT(DATETIME, Value, 101)
ELSE NULL END >= '20100101';
Run Code Online (Sandbox Code Playgroud)
另请注意,仅仅因为您WHERE对PK值执行了一个子句,并不意味着SQL Server必须首先评估该条件.它可能会尝试将视图中的每一行(heck,源表中的每一行)转换为DATETIME第一行.这就是为什么我还在列表中添加了一个CASE表达式SELECT,以防万一.没有双关语.我还提出了如何轻松计算本月第一天的建议(许多人倾向于做一些非常奇怪的事情,比如转换为字符串).
如果视图将单独的列暴露为日期时间,例如,您是否知道此查询会变得多么简单?
, DateValue = CASE WHEN ISDATE(Value) = 1 THEN CONVERT(DATETIME, Value, 101)
Run Code Online (Sandbox Code Playgroud)
那么查询可以是:
SELECT SalesItemPK, FieldName, DateValue,
FirstOfMonth = DATEADD(DAY, 1-DAY(DateValue), DateValue)
FROM [Oasis].[dbo].[vw_SALES_SalesItemDetails]
WHERE SalesItemPK IN (1425,1225,1556,1589,1599,1588,1590)
AND DateValue >= '20100101';
Run Code Online (Sandbox Code Playgroud)
实际上,视图也可以FirstOfMonth为您公开计算.
这些是为什么你永远不应该将日期/时间数据存储为字符串的众多原因中的一部分.至少,更改视图以将这些字符串显示为完全语言,日期格式和区域中性的字符串(yyyymmdd)而不是mm/dd/yyyy.
| 归档时间: |
|
| 查看次数: |
530 次 |
| 最近记录: |