SELECT Files.URL, Files.MD5, Files.Thumbnail, Files.Title, CONVERT(DATE, AttributeData.Keyword) AS DateUpdated, Attributes.Name AS DateType,
Metadata.metadata
FROM Files INNER JOIN
Metadata ON Files.ID = Metadata.FileID INNER JOIN
FilesToAttributeData ON Files.ID = FilesToAttributeData.FileID INNER JOIN
AttributeData ON FilesToAttributeData.AttributeDataID = AttributeData.ID INNER JOIN
Attributes ON AttributeData.AttributeID = Attributes.ID
WHERE (Files.GeneralSearch = 1) AND
(Attributes.Name = 'Process Date' OR Attributes.Name = 'Publish Date') AND
(ISDATE(AttributeData.Keyword) = 1) AND
(CONVERT(DATE, AttributeData.Keyword) > DATEADD(DAY, - 90, GETDATE()))
ORDER BY DateUpdated DESC
这是我原来的sql查询。它似乎可以在我们的开发环境中使用我们的数据。但在生产中我收到以下错误。 “Msg 241,Level 16,State 1,Line 1 从字符串转换日期和/或时间时转换失败。“。现在,如果我删除SELECT中的转换函数并输出AttributeData.Keyword它将正常工作。如果我单独留下并删除where子句中的转换函数如果它们都存在,它将无法正常工作。
任何可能导致此问题的想法?我试过CAST,我尝试过使用特定的日期样式。我们的日期通常看起来像yyyymmdd。一个例子是'20110318'。如果我用此字符串替换AttributeData.Keyword,它也将失败。我真的不知道这里发生了什么。
以下是一个有效的查询示例。
SELECT (AttributeData.Keyword) AS DateUpdated, Attributes.Name AS DateType
FROM Files INNER JOIN
Metadata ON Files.ID = Metadata.FileID INNER JOIN
FilesToAttributeData ON Files.ID = FilesToAttributeData.FileID INNER JOIN
AttributeData ON FilesToAttributeData.AttributeDataID = AttributeData.ID INNER JOIN
Attributes ON AttributeData.AttributeID = Attributes.ID
WHERE (Files.GeneralSearch = 1) AND
(Attributes.Name = 'Process Date' OR Attributes.Name = 'Publish Date') AND
(ISDATE(AttributeData.Keyword) = 1) AND
(CONVERT(DATE, AttributeData.Keyword) > DATEADD(DAY, - 90, GETDATE()))
ORDER BY DateUpdated DESC
DateUpdated DateType
20110318 Process Date
20110318 Process Date
20110315 Process Date
20110315 Process Date
20110303 Process Date
20110303 Publish Date
20110302 Process Date
20110301 Process Date
20110301 Publish Date
20110225 Process Date
20110223 Process Date
20110201 Publish Date
20110201 Process Date
20110127 Process Date
20110118 Publish Date
20110101 Publish Date
20110101 Publish Date
20101231 Process Date
20101231 Publish Date
答案 0 :(得分:3)
在SQL Server中,除了CASE
语句之外,没有任何特定的评估顺序,因此它可能会在CONVERT(DATE, AttributeData.Keyword)
过滤器之前执行ISDATE(AttributeData.Keyword) = 1
(您可以通过查看执行计划)。
要解决此问题,您可以将CONVERT(DATE, AttributeData.Keyword)
替换为
CASE
WHEN ISDATE(AttributeData.Keyword) = 1 THEN
CONVERT(DATE, AttributeData.Keyword)
END
所以你可以尝试
SELECT Files.URL,
Files.MD5,
Files.Thumbnail,
Files.Title,
CASE
WHEN ISDATE(AttributeData.Keyword) = 1 THEN
CONVERT(DATE, AttributeData.Keyword)
END AS DateUpdated,
Attributes.Name AS DateType,
Metadata.metadata
FROM Files
INNER JOIN Metadata
ON Files.ID = Metadata.FileID
INNER JOIN FilesToAttributeData
ON Files.ID = FilesToAttributeData.FileID
INNER JOIN AttributeData
ON FilesToAttributeData.AttributeDataID = AttributeData.ID
INNER JOIN Attributes
ON AttributeData.AttributeID = Attributes.ID
WHERE ( Files.GeneralSearch = 1 )
AND ( Attributes.Name = 'Process Date'
OR Attributes.Name = 'Publish Date' )
AND ( CASE
WHEN ISDATE(AttributeData.Keyword) = 1 THEN
CONVERT(DATE, AttributeData.Keyword)
END > DATEADD(DAY, -90, GETDATE()) )
ORDER BY DateUpdated DESC
答案 1 :(得分:1)
您也可以尝试添加
(ISDATE(AttributeData.Keyword) = 1)
作为AttributeData的连接条件,但我认为你仍然不能保证执行顺序。
答案 2 :(得分:0)
这似乎工作得很好......
DECLARE @tempFiles TABLE(DateUpdated varchar(MAX))
INSERT INTO @tempFiles(DateUpdated)
SELECT AttributeData.Keyword AS DateUpdated
FROM Files INNER JOIN
Metadata ON Files.ID = Metadata.FileID INNER JOIN
FilesToAttributeData ON Files.ID = FilesToAttributeData.FileID INNER JOIN
AttributeData ON FilesToAttributeData.AttributeDataID = AttributeData.ID INNER JOIN
Attributes ON AttributeData.AttributeID = Attributes.ID
WHERE (Files.GeneralSearch = 1) AND
(Attributes.Name = 'Process Date' OR Attributes.Name = 'Publish Date') AND
(ISDATE(AttributeData.Keyword) = 1) AND
(CONVERT(DATETIME, AttributeData.Keyword, 112) > DATEADD(DAY, - 90, GETDATE()))
ORDER BY DateUpdated DESC
SELECT CONVERT(DATE, DateUpdated) FROM @tempFiles
看来Martin是正确的,因为SQL优化器正在重新排序哪些部分首先被评估,这意味着在ISDATE之前发生转换,所以我实际上正在处理无效日期。 ATM我知道解决这个问题的唯一方法就是使用临时表并在select语句中进行评估,直到我准备好返回结果...