SQL Server ->> 內置標量函數TRY_PARSE、TRY_CAST和TRY_CONVERT的各自特點和區別


SQL Server到了目前的2014版本有三個函數是用來轉換數據格式的。雖說之前版本中已經有CAST和CONVERT這兩個函數來干這個事情。問題是,一旦往目標數據類型轉換失敗就會造成報錯。

TRY_PARSE、TRY_CAST和TRY_CONVERT的共同特點:

1)即便轉換失敗也不會造成整個語句報錯,只會在無法轉換的情況下輸出NULL值;

 

TRY_PARSE:

TRY_PARSE是用於將字符串類型的數據轉換成時間或者數值類型的數據。它是一個基於.NET CLR Runtime的標量函數。語法是TRY_PARSE(<string/string column> AS <data_type> [USING <culture>])

下面做一個字符串轉時間的實驗:

SQL Server 版本:

Microsoft SQL Server 2014
Enterprise Edition (64-bit) on Windows NT 6.3 <X64> 

SELECT TRY_PARSE('20150901' AS DATETIME), TRY_CAST('20150901' AS DATETIME), TRY_CONVERT(DATETIME,'20150901') 
SELECT TRY_PARSE('2015/09/01' AS DATETIME), TRY_CAST('2015/09/01' AS DATETIME), TRY_CONVERT(DATETIME,'2015/09/01')
SELECT TRY_PARSE('2015/09/01 14:14:45' AS DATETIME), TRY_CAST('2015/09/01 14:14:45' AS DATETIME), TRY_CONVERT(DATETIME,'2015/09/01 14:14:45')
SELECT TRY_PARSE('2015/09/01 14:14:45' AS DATETIME), TRY_CAST('2015/09/01 14:14:45' AS DATETIME), TRY_CONVERT(DATETIME,'2015/09/01 14:14:45')
SELECT TRY_PARSE('2015/09/01 14:14:45+0001' AS DATETIME), TRY_CAST('2015/09/01 14:14:45+0001' AS DATETIME), TRY_CONVERT(DATETIME,'2015/09/01 14:14:45+0001')

上面代碼輸出的結果如下圖所示

可以看到TRY_PARSE在將純數字轉為DATETIME的情況下居然失效,這點讓我非常意外,而且我嘗試了DATE類型也是一樣的結果。

而如果加了像"-"或者"/"這樣的時間分隔符則三個函數都能轉換成功。

還有一點讓我驚訝的是TRY_CAST和TRY_CONVERT不支持帶有時區的轉換,而TRY_PARSE則可以。

而當我把第四行代碼的冒號修改成中文下面的冒號時則SQL Server辨認不出來。

 

TRY_CAST和TRY_CONVERT:

這一對更多是CAST和CONVERT這對函數的變體,語法上一樣,只是當無法成功轉換的時候是報錯或者輸出NULL值。

 

三者的區別總結如下:

1)TRY_PARSE只支持字符轉數值或者時間類型,而TRY_CAST和TRY_CONVERT支持更多的類型;

2)三者有一點比較好的就是對於字符的空格處理,只要空格在處在分割符號的前后像“2015/    09/   10”這樣是可以被成功處理的,但是如果空格隔開本身就是一個整體的數據值部分,則全部不能識別,像“2015/0   9/10”。

2)TRY_PARSE由於是CLR寫的函數,對於源數據的數據格式支持比較廣或者要求比較寬松,而TRY_CAST和TRY_CONVERT則要求比較嚴格。這點從上面的例子中,TRY_PARSE支持帶有時區的時間格式而其他兩個不支持就可以看出。而TRY_PARSE的支持范圍遠不止於此。

下面這個例子就證明了TRY_PARSE是僅最大的努力和可能去轉換數據,而后兩者則需要很嚴格數據格式

SELECT TRY_PARSE('Thursday, 19 Nov 2015' AS DATETIME)  
SELECT TRY_CONVERT(DATETIME, 'Thursday, 19 Nov 2015'); 

 

 

-------------------------------------- update 2015/12/09 ----------------------------------------------

TRY_PARSE和TRY_CAST在把字符轉換成數值這一功能上,TRY_PARSE在某種情況下要比TRY_CAST差。這里做個實驗。

SELECT  Column1, 
        TRY_CAST(Column1 AS FLOAT) AS TRY_CAST, 
        TRY_CAST(REPLACE(Column1,',','') AS FLOAT) AS TRY_CAST_REMOVE_COMMA, 
        TRY_PARSE(Column1 AS FLOAT) AS TRY_PARSE, 
        TRY_PARSE(REPLACE(Column1,',','') AS FLOAT) AS TRY_PARSE_REMOVE_COMMA   
FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0'
                ,'Excel 12.0 Xml;HDR=YES;IMEX=1;Database=D:\1.xlsx'
                ,'SELECT * FROM [sheet1$]');

上面語句的結果

 

我的源文件內容是這樣的:

Column1
123,456
123456.789
123456
2,464
   210,860 
ABC

 

 

 

 

 

 

 

 

可以看到結果中對於第5行的轉換TRY_PARSE沒能把數字前后類似於空格的特殊字符忽略。這點上TRY_CAST應該說做得更加好。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM