sql server - 检查是否可以进行强制转换

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14719760/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-01 13:30:31  来源:igfitidea点击:

sql server - check to see if cast is possible

sqlsql-serversql-server-2008tsql

提问by Bruce

I have the following code to cast nvarchar to integer:

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

     cast(@value as int)

However I have no control of the parameter @value, hence the code might fail. Is there anyway to check if a cast is possible before doing a cast?

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

回答by Matt

Well, in SQL Server 2012 you could use the new TRY_CAST(), but with SQL Server 2008, you should be able to use ISNUMERIC(), and then include handling for values that do not pass that test.

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

回答by sgeddes

I've recently answered a question about this and using ISNUMERICto CASTto an INTwon't work by itself. Reason being, ISNUMERICreturns true for non integer numbers (1.5) for example.

我最近回答了这个和使用问题ISNUMERIC,以CAST一种INT不会自行工作。原因是,例如,ISNUMERIC对于非整数 (1.5) 返回 true。

Here was a recent answer on the subject:

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

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

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

Consider adding an additional check using CHARINDEX with ISNUMERIC, or what I prefer, use a Regular Expression to validate the data.

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

And here is a Fiddledemonstrating the problem with using ISNUMERIC on it's own. And the Fiddleusing a regular expression instead that works.

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

Good luck.

祝你好运。

回答by Michael Erickson

I generally use the following, it seems to cover all the situations.

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

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

It takes advantage of the fact that "ISNUMERIC" will not allow two periods. The "TRY_CAST" in SQL Server 2012+ is a much better solution though.

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

回答by Gordon Linoff

The proper test is:

正确的测试是:

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

The function isnumeric()returns 1 for anything that looks like a float, so you have to be careful.

isnumeric()对于任何看起来像浮点数的东西,该函数返回 1,所以你必须小心。

You can also use what I consider to be a peculiarity of SQL Server. You can cast the floating value 1.23 to an int, but you cannot cast the string value. So, the following also works:

您还可以使用我认为是 SQL Server 的一个特性。您可以将浮点值 1.23 转换为 int,但不能转换字符串值。因此,以下也有效:

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

回答by Anoop Verma

Maybe we can do something like this:

也许我们可以这样做:

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

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

回答by cmdr_putin

Use a procedure with a TRY CATCH block to suppress errors

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

i.e.

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

Now you can call that with the passed string and desired type and the proc returns 1 for success and 0 for failure

现在您可以使用传递的字符串和所需的类型调用它,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'