28

我有以下代码将 nvarchar 转换为整数:

     cast(@value as int)

但是我无法控制参数@value,因此代码可能会失败。无论如何,在进行演员表之前检查是否可以演员表?

4

6 回答 6

32

好吧,在 SQL Server 2012 中,您可以使用新的TRY_CAST(),但在 SQL Server 2008 中,您应该能够使用ISNUMERIC(),然后包括对未通过该测试的值的处理。

于 2013-02-06T01:02:07.917 回答
12

我最近回答了一个关于此的问题,并且使用toISNUMERIC本身不会起作用。原因是,例如,对于非整数 (1.5) 返回 true。 CASTINTISNUMERIC

这是有关该主题的最新答案:

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

考虑使用带有 ISNUMERIC 的 CHARINDEX 添加额外的检查,或者我更喜欢使用正则表达式来验证数据。

这是一个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 

祝你好运。

于 2013-02-06T01:34:42.410 回答
8

我一般用下面的,好像涵盖了所有的情况。

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

它利用了“ISNUMERIC”不允许两个句点这一事实。SQL Server 2012+ 中的“TRY_CAST”是一个更好的解决方案。

于 2017-04-30T01:59:03.707 回答
2

正确的测试是:

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)
于 2013-02-06T01:53:57.280 回答
1

也许我们可以这样做:

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

begin try
    select cast(@value as int);
end try
begin catch
-- do something
end catch
于 2013-02-06T05:17:16.060 回答
0

使用带有 TRY CATCH 块的过程来抑制错误

IE

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'
于 2017-11-20T17:15:06.223 回答