Подтвердить что ты не робот

Sql server - проверьте, возможно ли использование

У меня есть следующий код для приведения nvarchar в integer:

     cast(@value as int)

Однако я не контролирую параметр @value, поэтому код может завершиться ошибкой. Есть ли все равно, чтобы проверить, возможно ли бросок, прежде чем делать литье?

4b9b3361

Ответ 1

Ну, в SQL Server 2012 вы можете использовать новый TRY_CAST(), но с SQL Server 2008 вы сможете использовать ISNUMERIC(), а затем включить обработку значений, которые не проходят этот тест.

Ответ 2

Недавно я ответил на вопрос об этом, и использование ISNUMERIC to CAST для INT не будет работать само по себе. Разум, ISNUMERIC возвращает true для не целочисленных чисел (1.5), например.

Вот недавний ответ на этот вопрос:

fooobar.com/questions/406975/...

Рассмотрите возможность добавления дополнительной проверки с помощью 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 

Удачи.

Ответ 3

Обычно я использую следующее: он, кажется, охватывает все ситуации.

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

Он использует тот факт, что "ISNUMERIC" не допускает двух периодов. Однако "TRY_CAST" в SQL Server 2012+ является гораздо лучшим решением.

Ответ 4

Возможно, мы можем сделать что-то вроде этого:

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

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

Ответ 5

Правильный тест:

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

Функция isnumeric() возвращает 1 для всего, что похоже на float, поэтому вы должны быть осторожны.

Вы также можете использовать то, что я считаю особенностью SQL Server. Вы можете присвоить значение переменной 1.23 для int, но вы не можете использовать строковое значение. Итак, также работает следующее:

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

Ответ 6

Используйте процедуру с блоком 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'