2017-10-10 65 views
1

下面是一些測試SQL。 IsNumeric表示05031,的子字符串是數字,但由於,而試圖將其轉換爲實際數字時失敗。這是SQL中的錯誤嗎?在t-sql中使用IsNumeric問題?

DECLARE @Str NVARCHAR(20) 

SET @Str = 'XYZ 505031, some text' 

SELECT CASE WHEN ISNUMERIC(SUBSTRING(@Str,6,7)) = 1 THEN CONVERT(int,SUBSTRING(@Str,6,7)) ELSE 0 END, SUBSTRING(@Str,6,7) 
+2

不是一個錯誤。該功能是有史以來最糟糕的命名功能。當該值能夠轉換爲遠程類似於數字的數種數據類型時,它的計算結果爲true。這是關於這個話題的更好的文章之一。 http://www.sqlservercentral.com/articles/ISNUMERIC()/71512/ –

+1

在這種情況下,雖然它不是'ISNUMERIC'的問題,但事實上,使用您的區域設置,您無法將數字以'INT'作爲逗號,但如果您嘗試將其轉換爲支持逗號的數字數據類型(例如'MONEY',yikes),則不存在問題 – Lamak

+0

@SeanLange謝謝您,它是一個愚蠢的函數。我將它更改爲TRY_PARSE並且工作得更好 – collinszac10

回答

2

你應該使用try_cast,因爲ISNUMERIC評估爲1爲5031,

對於某些不是數字的字符(如加號(+),減號( - )和有效貨幣符號(如美元符號($)),ISNUMERIC返回1。有關貨幣符號的完整列表,請參閱money和s​​mallmoney(Transact-SQL)。 DECLARE @Str NVARCHAR(20)

SET @Str = 'XYZ 505031, some text' 

SELECT 
    CASE 
     WHEN TRY_CAST(SUBSTRING(@Str,6,7) AS DECIMAL(10,2)) IS NOT NULL 
     THEN CONVERT(int,SUBSTRING(@Str,6,7)) 
     ELSE 0 
    END, 
    SUBSTRING(@Str,6,7) 
0

如果是2012+,可以使用Try_Convert()。我們用錢becase的了,這將轉換爲前導零,然後我們轉換爲int

DECLARE @Str NVARCHAR(20) 

SET @Str = 'XYZ 505031, some text' 

SELECT AsInt = IsNull(try_convert(int,try_convert(money,SUBSTRING(@Str,6,7))),0) 
    , AsStr = SUBSTRING(@Str,6,7) 

返回

AsInt AsStr 
5031 05031, 
0

這是因爲你的substring也被揪到底一個逗號。

SELECT SUBSTRING(@Str, 6, 7); 

是造成:

05031, 

然而,

SELECT SUBSTRING(@Str, 6, 5); 

是造成:

05031 

而且

SELECT CASE WHEN ISNUMERIC(SUBSTRING(@Str,6,5)) = 1 THEN CONVERT(int,SUBSTRING(@Str,6,5)) ELSE 0 END, SUBSTRING(@Str,6,5) 

被得到:

5031 | 05031 
+0

子字符串是正確的,ISNUMERIC給我一個不一致的結果 – collinszac10