2017-05-31 36 views
0

我有日期格式如下认为:日期是SQL Server之间的连字符字符串

Date_str 
19-12-2007 
31-7-2009 
3-1-2010 
31-11-2009 
etc. 

我不能做到以下几点:

CONCAT(RIGHT(Date_str,4),SUBSTRING(Date_str,3,3),LEFT(2)) 

,因为你可以看到上述情况,日期不一样长。 SQL Server中有没有将日期提取为日期时间/日期的方法?

我也试过

Convert(datetime, Date_str) 

,但它只是抛出一个错误:

The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.

+0

将它们存储为'YYYY-MM-DD',并避免在所有类型的SQL中使用此类:) – scsimon

+1

日期类型没有格式。只是*不*存储日期为字符串 –

+1

@scsimon相反,使用适当的日期类型,并避免任何问题。以字符串形式存储,您将永远无法修复所有错误。例如,尝试向该字符串添加一天。或检索月份*名称* –

回答

3

如果20 12+,我会使用Try_Convert()。这会将虚假日期返回为NULL。

Declare @YourTable Table ([Date_str] varchar(50)) 
Insert Into @YourTable Values 
('19-12-2007') 
,('31-7-2009') 
,('3-1-2010') 
,('31-11-2009') 

Select * 
     ,try_convert(date,Date_Str,105) 
from @YourTable 

返回

Date_str (No column name) 
19-12-2007 2007-12-19 
31-7-2009 2009-07-31 
3-1-2010 2010-01-03 
31-11-2009 NULL    -- Notice 11/31 is NOT a date 
+0

不错John Cappalletti!我只是在SELECT语句中使用它: SELECT TRY_CONVERT(datetime,Date_str,105)FROM TABLE – PRIME

+1

@PRIME Try_Convert可以使事情变得更简单。正如你所知道的那样,当日期被存储为叮咬时......一大堆可能会出错。 :) –

0

正如我在评论中提到的,唯一现实的解决方案是该字符串转换成适当的date -typed列。当前格式不允许进行日期排序,或者搜索日期范围,例如查找上周的日期或日期与其他日期之间的条目。

CONVERTTRY_PARSE解析意味着没有索引可用于加速查询。每次:

WHERE CONVERT(Date, Date_str, 105) > '20170101' 

时,服务器将不得不扫描整个表的数据,然后过滤行转换。

如果您无法更改字段本身的类型,则可以创建一个持久计算列,将该值作为日期返回并向其中添加索引。您可以使用该列的索引查询:

alter table SomeTable add date2 as TRY_convert(Actual_Date,date_str,105) PERSISTED 

create index IX_SomeTable_ActualDate on SomeTable (Actual_Date) 

这将允许你进行无技巧排序:

SELECT * 
FROM SomeTable 
ORDER BY Actual_Date 

或运行采取IX_SomeTable_ActualDate指数的优势范围查询:

SELECT * 
FROM SomeTable 
Where Actual_Date Between DATEADD(d,-7,GETDATE()) AND GETDATE() 

如果您有1000行,则性能可能会提高1000倍。

现有的应用程序甚至不会注意到这一变化。较新的查询和应用程序将能够利用索引和排序