2017-05-31 78 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倍。

現有的應用程序甚至不會注意到這一變化。較新的查詢和應用程序將能夠利用索引和排序