具体来说,我需要排除任何已经过了日期的记录.
我试过了:
SELECT * FROM tblServiceUseRSSchedule WHERE ScheduleEndDate !='' AND ScheduleEndDate < '2015/05/31'
这个选定的值,如17/06/2012和19/04/2015,已经通过,以及2015年6月1日尚未通过.
然后我尝试使用以下方式转换数据:
SELECT * FROM tblServiceUseRSSchedule WHERE CAST(ScheduleEndDate as DATETIME) < CAST('05/31/2015' as DATETIME) AND ScheduleEndDate !='' AND ScheduleEndDate is not null
但得到以下错误:
The coversion of a varchar data type to a datetime data type resulted
in an out-of-range value.
我检查了后面的数据,没有一个是null,没有空白空格.所有日期格式为dd / mm / yyyy.
我无法弄清楚如何比较存储与今天日期的varchar日期.
解决方法
如果可能,您应该更改表以将它们存储为日期数据类型.
您可以通过几个简单的步骤完成:
>将当前列(我猜测ScheduleStartDate也是varchar)重命名为columnName_old.这可以通过使用sp_rename
轻松完成.
>使用alter table
添加具有适当数据类型的列.
>使用update语句将旧列中的值复制到新列.由于所有日期都以相同的格式存储,您可以像这样使用convert
:set ScheduleStartDate = convert(date,NULLIF(ltrim(rtrim(ScheduleStartDate_old)),”),103)如果您的sql server版本是2012或更高,请使用try_convert
.注意我已使用nullif
,ltrim
和rtrim
将仅包含空格的值转换为null.
>删除并重新创建引用这些列的索引.最简单的方法是右键单击SSMS上的索引,然后选择脚本索引为 – >放下并创造.
>使用alter table删除旧列.
注意:如果在数据库的任何其他对象中引用这些列,则还必须更改这些对象.这包括存储过程,外键等.
如果您无法更改列的数据类型,并且您的sql server版本低于2012,则需要使用如下转换:
SELECT * FROM tblServiceUseRSSchedule WHERE CONVERT(DATE,NULLIF(ScheduleEndDate,RTRIM(LTRIM('')),103) < CAST(GETDATE() As Date); AND ScheduleEndDate IS NOT NULL
请注意,如果您的列的数据不是dd / MM / yyyy格式的单行,则会引发错误.
对于sql server版本2012或更高版本,请使用Try_convert.如果转换失败,此函数将返回null:
SELECT * FROM tblServiceUseRSSchedule WHERE TRY_CONVERT(DATE,103) < CAST(GETDATE() As Date); AND ScheduleEndDate IS NOT NULL
注意:我使用CAST(GETDATE()作为日期)来删除当前日期的时间部分.这意味着您只能获得ScheduleEndDate至少有一天的记录.如果您还想获取今天ScheduleEndDate所在的记录,请使用< =而不是<. 最后一件事:在where子句中使用列上的函数将阻止sql Server对这些列使用任何索引.这是您应将列更改为适当数据类型的另一个原因.