2017-05-31 90 views
0

我有一個列可以存儲文本,但用於存儲一個數字(我沒有製造系統!)有人已經把一個空值(即不是內容,但不空)及其導致的錯誤: -轉換數據類型(varchar)仍然顯示轉換錯誤

Msg 8114, Level 16, State 5, Line 1

Error converting data type varchar to numeric.

我有問題降低到以下: -

SELECT 
    T1.[FIELD_5], 
    ISNUMERIC(T1.[FIELD_5]), 
    NULLIF(T1.[FIELD_5],''), 
    ISNULL(NULLIF(T1.[FIELD_5],''),0), 
    CONVERT(DECIMAL(18,5),ISNULL(NULLIF(T1.[FIELD_5],''),0)) 
FROM 
    [MyTBL] T1 
ORDER BY 
    ISNUMERIC(T1.[FIELD_5]) 

問題的數據是[FIELD_5]

  1. 我可以看到SQL認爲的不是數字的值
  2. 我可以看到NULLIF成功將其更改爲一個NULL
  3. 我可以看到ISNULL正在轉動NULLIF結果0

但在CONVERT上的錯誤消息ISNULL結果的結果,我希望它導致0.00000

+0

SQL服務器的什麼版本?在以後的版本中,您可以使用TRY_PARSE – DhruvJoshi

+0

您確定沒有空格或不可打印的字符嗎?你知道'ISNUMERIC()'的侷限性嗎? – HoneyBadger

+0

我無法解釋它是如何被捕獲的,但我已經給出瞭解釋'1E-07'的解釋,並將其視爲數字。 –

回答

0

這是一個需要更好的調查的情況下,我應該已經意識到,因爲我認爲SQL不通常是用戶錯誤。

我再次運行它而沒有order by子句,然後選擇在顯示最後一行(即導致錯誤的那行)後顯示的行。

[FIELD_5]包含值爲1E-07,這是一個臭名昭着的Excel導入錯誤!

什麼不加起來就是爲什麼當我通過ISNUMERIC開始訂單時,我沒有在列表頂部看到這個值,只有確實正確管理的空白值。

問題解決了,我應該堅持調查,但我認爲這值得留下來幫助未來的其他調查。

+1

如果你運行'SELECT ISNUMERIC('1E-07')',你會看到它返回'1'。在評估數字時,「ISNUMERIC()」是非常寬容的。像'$,+,-'這樣的字符都被評估爲1。 – HoneyBadger

+1

>>>什麼不加起來就是爲什麼當我通過ISNUMERIC訂購時,我沒有在列表頂部看到這個值,只有確實正確管理的空白值。<<< isnumeric( 1E-07)= 1,這就是爲什麼當你用isnumeric命令時它不會彈出。 Isnumeric看起來並不是你想要轉換成十進制(18,5),它只是告訴你它是否可以轉換爲某種數字類型,並且是的,1E-07會。它可以轉換爲浮動 – sepupic

2

使用try_convert()

SELECT T1.[FIELD_5], ISNUMERIC(T1.[FIELD_5]), NULLIF(T1.[FIELD_5], ''), 
     COALESCE(NULLIF(T1.[FIELD_5], ''), 0), 
     TRY_CONVERT(DECIMAL(18, 5), COALESCE(NULLIF(T1.[FIELD_5], ''), 0)) 
FROM [MyTBL] T1 
ORDER BY ISNUMERIC(T1.[FIELD_5]); 

try_convert()在SQL Server 2012中引入。如果您使用的是早期版本,那麼您需要使用case表達式。

(我切換ISNULL()COALESCE()因爲我喜歡那裏的實際使用ANSI標準的功能。)

0

有一些可用非數字值,你可以這樣做檢查以案例如下:

select convert(decimal(18,5), '') 

拋出誤差爲「錯誤數據類型爲varchar轉換爲數字。 」

SELECT 
    T1.[FIELD_5], 
    ISNUMERIC(T1.[FIELD_5]), 
    NULLIF(T1.[FIELD_5],''), 
    ISNULL(NULLIF(T1.[FIELD_5],''),0), 
    CONVERT(DECIMAL(18,5), iif(isnumeric(ISNULL(T1.[FIELD_5]),'0') > 1,T1.[FIELD_5],'0') 
    ISNULL(NULLIF(T1.[FIELD_5],''),0)) 
FROM 
    [MyTBL] T1 
ORDER BY 
    ISNUMERIC(T1.[FIELD_5]) 
1

SQL2012 +

爲了找到那些無效DECIMAL|NUMERIC(18, 5)我會使用從而TRY_PARSETRY_CONVERT函數的值:

SELECT 
    T1.ID, 
    NULLIF(T1.[FIELD_5], '') AS FIELD_5_WithNULLIF 
FROM 
    [MyTBL] T1 
WHERE 
    T1.[FIELD_5] IS NOT NULL -- It removes from end results NULLs (FIELD_5) 
    AND T1.[FIELD_5] <> '' -- It removes empty or SPACE(n) values (FIELD_5) 
    AND TRY_PARSE(T1.[FIELD_5] AS DECIMAL(18, 5)) IS NULL -- It removes invalid DECIMAL(18, 5) values (FIELD_5) 

TRY_PARSE行爲是如下:如果源字符串值[N][VAR]CHAR是一個有效的DECIMAL|NUMERIC(18, 5)然後它返回該值與新的數據類型否則它返回NULL - >所以它不會引發異常(「錯誤」)。

參見:Use new TRY_PARSE() instead of ISNUMERIC() | SQL Server 2012

現在,如果你要轉換的空字符串,也無效源的值設爲NULL,然後我會用

SELECT 
    T1.ID, 
    T1.[FIELD_5] AS OriginalValue, 
    TRY_PARSE(T1.[FIELD_5] AS DECIMAL(18, 5)) AS ConvertedValue 
FROM 
    [MyTBL] T1 
相關問題