将varchar转换为Date,而不是在WHERE子句中使用AND

时间:2014-08-13 15:37:30

标签: sql-server

我有一个SQL Server表Companies,其中包含UserDefined4类型的列nvarchar(100)

此列包含一些文字以及格式为DD.MM.YYYY

的日期

我想选择2014年3月和4月的记录。

我正在运行此查询,

SELECT 
    (Right(Companies.UserDefined4, 10)) 
FROM   
    Companies
WHERE  
    (Right(Companies.UserDefined4, 10) not like '%[^0-9.]%' 
    AND (Right(Companies.UserDefined4, 10) not like '')) 
    AND (CONVERT(Date,Right(Companies.UserDefined4, 10),104) >= '2014-03-01' 
         and 
         CONVERT(Date,Right(Companies.UserDefined4, 10),104) <= '2014-04-30')

此查询引发错误

  

将字符串转换为日期和/或时间时出错。

我已经逐一检查了所有记录,并且它们以适当的格式包含日期。对我来说奇怪的是,如果我在同一个查询的后续部分中放置OR而不是AND,则会运行相同的查询:

(
         CONVERT(Date,Right(Companies.UserDefined4, 10),104) >= '2014-03-01' 
          OR 
         CONVERT(Date,Right(Companies.UserDefined4, 10),104) <= '2014-04-30'
)

我知道,将日期保存为NVarChar并不是明智的决定,但我必须处理这些数据。我不是设计这个数据库的人。

2 个答案:

答案 0 :(得分:3)

我过去曾遇到过类似的问题,而且这些问题都是由于某些专栏没有以预期的字符(在你的情况下为日期)和&#34;警卫条款&#34; (在您的情况下,WHERE中的前两个条件)不会阻止查询引擎应用&#34;范围条件&#34; (在您的情况下,WHERE中的最后两个条件。)

请注意,我并不确切知道为什么会发生这种情况(可能是查询优化,没有&#34;短路&#34;评估或评估发生的顺序不是我们所期望的 - - 这是我推测的),但是我注意到如果你在一个临时结构(例如一个表变量)中存储查询的中间结果(只有&#34; guard子句&#34;应用)然后应用&#34;范围条款&#34;对于那个中期结果,它将起作用。

例如,即使存在&#34;坏&#34;行(不以日期结束的行):

DECLARE @t TABLE (userdate CHAR(10))

INSERT @t
SELECT RIGHT(Companies.UserDefined4, 10)
FROM Companies
WHERE RIGHT(Companies.UserDefined4, 10) NOT LIKE '%[^0-9.]%'
    AND RIGHT(Companies.UserDefined4, 10) <> ''

SELECT *
FROM @t
WHERE CONVERT(DATE, userdate, 104) >= '2014-03-01'
    AND CONVERT(DATE, userdate, 104) <= '2014-04-30'

您可以查看演示问题的小提示here

答案 1 :(得分:2)

你能够确定 UserDefined4真的始终包含最右边10个字符的那种格式的日期吗?

如果是这样,您可以像这样创建一个计算列

ALTER TABLE dbo.Companies
ADD DateFromUD4 AS CONVERT(DATE, RIGHT(UserDefined4, 10), 104) PERSISTED

然后查询变得非常简单:

SELECT 
    (list of columns)
FROM   
    dbo.Companies
WHERE  
    DateFromUD4 >= '20140301' AND 
    DateFromUD4 <= '20140430'

我喜欢使用 ISO-8601 格式(YYYYMMDD没有任何破折号)将日期指定为字符串,因为这可以保证在任何 SQL上运行服务器,无论日期和语言设置如何。

由于转换为DATE,您也不必担心时间部分 - 这是仅限日期计算列。这适用于SQL Server 2008 和更新版本。

相关问题