2013-02-06 172 views

回答

21

那麼,在SQL Server 2012中,您可以使用新的TRY_CAST(),但對於SQL Server 2008,您應該能夠使用ISNUMERIC(),然後包含對未通過該測試的值的處理。

+5

-1:select isnumeric('1.');選擇投射('1。'int); – Pete

+0

ISNumeric('a1a')返回1,但是你永遠不能投('a1a'爲float) – CodingTT

+0

我相信你的意思是SQL Server 2014:https://msdn.microsoft.com/en-us/library/hh974669.aspx –

10

我最近回答了一個關於這個問題,並使用ISNUMERICCASTINT不會自行工作。原因在於,例如,ISNUMERIC對非整數(1.5)返回true。

這裏是關於這個問題的答案最近:

https://stackoverflow.com/a/14692165/1073631

考慮增加使用CHARINDEX與ISNUMERIC額外的檢查,或者是我願意的話,使用正則表達式來驗證數據。

這裏是一個Fiddle演示自己使用ISNUMERIC的問題。而Fiddle使用正則表達式代替它的作用。

DECLARE @Test nvarchar(10) 
SET @Test = '1.5' 
--Works 
SELECT CASE WHEN @Test NOT LIKE '%[^0-9]%' THEN CAST(@Test as int) ELSE 0 END 
-- Produces Error 
SELECT CASE WHEN ISNUMERIC(@Test) = 1 THEN CAST(@Test as int) ELSE 0 END 

祝你好運。

+0

+1。 。 。第一個是正確的。你的答案應該更清楚一點,第二個是錯誤的(我必須滾動才能看到「產生錯誤」)。 –

+0

你也應該防範溢出(並可選擇允許負整數):http://stackoverflow.com/a/24250511/1149773 – Douglas

0

適當的測試是:

select (case when isnumeric(val) = 1 and val not like '%e%' and val not like '%.%' 
      then cast(val as int) 
     end) 

功能isnumeric()返回1的任何東西,看起來像一個浮動,所以你必須要小心。

你也可以使用我認爲是SQL Server的一個特性。您可以將浮點值1.23轉換爲int類型,但不能投射字符串值。所以,以下也適用:

select (case when isnumeric(val) = 1 
      then cast(cast(val as float) as int) 
     end) 
+1

不,這是錯誤的。 'isnumeric('+')== 1'。 'isnumeric(' - ')== 1'。 'isnumeric'是一個可怕的實現,他們的回答讓你開放到多個邊緣情況下,儘管你檢查了'cast'到'int'將會失敗。 – mattmc3

+0

@ mattmc3。 。你有沒有注意到OP基本接受了這個答案。另外,轉換爲'float'可以修復許多這些問題(儘管不會溢出)。 –

+0

接受的答案獲取SQL 2012+的TRY_CAST部分。要使用ISNUMERIC,你必須做很多體操來處理邊緣情況。例如,將「+」或「 - 」作爲「val」的值插入。對'浮動'的演員陣容將會非常壯觀。 (^^不是我的downvote順便說一句 - 我更喜歡評論來表示傷害)。這個答案給出了一種使用'ISNUMERIC'來實際處理邊界情況並確保你有一個正確的'TRY_CAST'替代方法:http://stackoverflow.com/questions/4522056/how-to-determine-the-field-value -which-can-not-convert-to-decimal-float-int-i – mattmc3

1

也許我們可以做這樣的事情:

declare @value as nvarchar(10) = 'A'; 

begin try 
    select cast(@value as int); 
end try 
begin catch 
-- do something 
end catch 
+0

我喜歡這種方法,但是我們不能在SELECT語句中做到這一點,我們可以嗎? –

2

我一般採用下面,似乎涵蓋所有的情況。

SELECT CASE WHEN 1 = ISNUMERIC(@value + '.0') THEN CAST(@value as int) ELSE 0 END 

它利用了「ISNUMERIC」不允許兩個週期的事實。儘管SQL Server 2012+中的「TRY_CAST」是一個更好的解決方案。

0

使用過程用try catch塊壓制錯誤

CREATE PROCEDURE p_try_cast 
@type nvarchar(MAX), 
@value nvarchar(MAX) 
AS 
BEGIN 

    BEGIN TRY 
     DECLARE @sql  varchar(MAX) 
     DECLARE @out_table TABLE(value varchar(MAX)) 

     SET @sql = 'SELECT CONVERT(varchar(max), CAST(''' + @value + ''' AS ' + @type + '))' 

     INSERT @out_table 
     EXECUTE (@sql) 

     IF EXISTS (SELECT 1 FROM @out_table WHERE value = @value) 
      RETURN 1 

     RETURN 0 
    END TRY 
    BEGIN CATCH 
     RETURN 0 
    END CATCH 

END 

GO 

現在你可以調用與傳遞的字符串和所需類型和proc的失敗則返回1成功和0

DECLARE @ret int 

-- This returns 0 - Fail 
EXEC @ret = p_try_cast 'integer', '1.5' 

-- This returns 1 - Success 
EXEC @ret = p_try_cast 'integer', '1.5' 

-- This returns 0 - Fail 
EXEC @ret = p_try_cast 'char(4)', 'HELLO' 

-- This returns 1 - Success 
EXEC @ret = p_try_cast 'char(4)', 'HELL' 
相關問題