奇怪的是,日期被解释为 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;
(如果你发现有问题的行,显然,修复它们。)
您还可以使用以下方法确保将值解释为 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';
另请注意,仅仅因为您WHERE
对 PK 值执行了一个子句,并不意味着 SQL Server 必须首先评估该条件。它可以尝试将视图中的每一行(哎呀,源表中的每一行)转换为DATETIME
第一行。这就是为什么我还在列表中添加了一个CASE
表达式SELECT
,以防万一。没有双关语的意思。我还提出了如何轻松计算本月第一天的建议(很多人倾向于做非常奇怪的事情,比如转换为字符串)。
如果视图将单独的列公开为日期时间,您是否知道此查询会简单得多,例如
, DateValue = CASE WHEN ISDATE(Value) = 1 THEN CONVERT(DATETIME, Value, 101)
那么查询可能是:
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';
事实上,视图也可以FirstOfMonth
为您公开计算。
这些是您永远不应将日期/时间数据存储为字符串的众多原因中的一些。至少,更改视图以将这些字符串显示为完全与语言、日期格式和区域无关的字符串 ( yyyymmdd
) 而不是mm/dd/yyyy
.