2014-04-02 85 views
0

不幸的是,我遇到了一個數據庫,它將日期存儲爲varchar而不是datetime。它存儲多種日期格式(例如xx/yy/zzzz,xx/yy/zz,x/y/zzzz等)。最後,我希望將它們全部轉換爲xx/yy/zzzz。無法將varchar轉換爲datetime

我想做一些數據清理並嘗試一些SELECT語句來查看可以轉換爲什麼。

SET DATEFORMAT DMY 
SELECT MyDate, CAST(MyDate AS DATETIME) AS MyDate_Mod FROM MyTable 
WHERE ISDATE(MyDate) <> 0 AND MyDate NOT LIKE '__/__/____' 

這似乎執行確定。

下一個目標是找到與年大於2000的日期,因爲2位數的年份(如XX/YY/ZZ)的一些CAST自動轉換爲20zz而不是19zz。 反正所以我更新了SELECT到:

SELECT MyDate, CAST(MyDate AS DATETIME) AS MyDate_Mod FROM MyTable 
WHERE ISDATE(MyDate) <> 0 AND MyDate NOT LIKE '__/__/____' AND YEAR(CAST(MyDate AS DATETIME)) >= 2000 

運行上面的語句失敗,轉換的問題。

也許我想執行的順序要緊的CAST在WHERE語句可能ISDATE <> 0

修改語句之前已經執行:

SELECT * FROM (SELECT MyDate, CAST(MyDate AS DATETIME) AS MyDate_Mod FROM MyTable 
    WHERE ISDATE(MyDate) <> 0 AND MyDate NOT LIKE '__/__/____') AS Sub 
WHERE YEAR(Sub.MyDate_Mod) >= 2000 

這也失敗了。

有人可以向我解釋爲什麼它失敗,如果它正在尋找一個有效的ISDATE(MyDate)?

回答

1

目前還是不允許評論(但將其視爲一個)。對於第三個查詢確實嘗試這樣的:

SELECT Top 10 Sub.*, Datepart(year,Sub.MyDate_Mod) 
FROM 
    (SELECT MyDate, CAST(MyDate AS DateTime) AS MyDate_Mod 
    FROM MyTable 
    WHERE ISDATE(MyDate) <> 0 AND MyDate NOT LIKE '__/__/____') AS Sub 

這也只是看看你是否得到任何結果,或者如果它總是拋出一個錯誤。如果它工作,然後嘗試將其移動到WHERE子句。

+0

我試過了,它的工作原理。但是,如果將Datepart()放入WHERE子句中,它將失敗並顯示相同的轉換錯誤。奇怪的!!! – James

+0

好奇再次,如果你是嵌套SELECT語句作爲,所以你只是做一個SELECT * FROM ...其中alias_for_date_part> = 2000可以嗎?並不是它是最乾淨的代碼,但那很奇怪。 –

+0

我的假設是,SQL執行計劃除了拉聲明,並重新排序,以最佳水平(其視圖)和後來不知何故執行ISDATE。 – James