Проверить, является ли varchar числом (TSQL)

есть ли простой способ выяснить, является ли varchar числом?

Примеры:

abc123 --› без номера

123 --› да, это номер

Спасибо :)


person grady    schedule 05.01.2011    source источник


Ответы (9)


ISNUMERIC подойдет

Также проверьте раздел ПРИМЕЧАНИЯ в статье.

person Sachin Shanbhag    schedule 05.01.2011
comment
@Grady - я думаю, что ответ Дэмиена ниже лучше, как указано, у IsNumeric есть некоторые ограничения. Вы уверены, что не сталкиваетесь с такими ограничениями? - person Sachin Shanbhag; 05.01.2011
comment
прокрутите вниз, чтобы увидеть следующий ответ. - person greg121; 19.10.2015
comment
select isnumeric('138D47') возвращает 1 - person nuzzolilo; 29.10.2015
comment
-1 Есть много вещей, для которых isNumeric верно, но которые будут исключены, если они будут приведены к INT или Float — см. brentozar.com/archive/2018/02/fifteen-things-hate-isnumeric для некоторых примеров, который показывает, что все следующие 15 строк IsNumeric=1 '$' ,'£' ,',' ,'.' ,'0e+99','2e2','12D4',',1,1,1,1,1,1,1','-','+',CHAR(9),CHAR(10), СИМВОЛ(11), СИМВОЛ(12), СИМВОЛ(13) - person Andrew Hill; 28.02.2018
comment
@Nuzzolilo Потому что это кажется числовым, если это шестнадцатеричная вещь, а d является частью шестнадцатеричной вещи - person Valentin C; 09.07.2018
comment
Я все еще получаю сообщение об ошибке в приведенном ниже запросе. Объявите @testVal как varchar (50) = 'ok' выберите CASE WHEN IsNUMERIC (@ testVal) = 1 THEN Cast (@ testVal as numeric) ELSE 'n' End Ошибка преобразования типа данных varchar в числовой . - person KetanVaghasiya; 17.10.2018

ISNUMERIC не подойдет — он говорит вам, что строка может быть преобразована в любой из числовых типов, что почти всегда является бессмысленной информацией. Например, согласно ISNUMERIC все следующие числа являются числовыми:

£, $, 0d0

Если вы хотите проверить цифры и только цифры, вам нужно отрицательное выражение LIKE:

not Value like '%[^0-9]%'
person Damien_The_Unbeliever    schedule 05.01.2011
comment
ISNUMERIC также считает - числовым. - person Ewald Stieger; 01.08.2014
comment
Это отличный метод, если вам нужны только положительные целые числа, но я добавил несколько примеров ниже, если вам нужно разрешить и другие типы числовых типов, если вы используете SQL 2012+. - person Dan Field; 18.03.2016
comment
Определенно, лучший ответ, чем ISNUMERIC! Это должно быть помечено как правильный ответ. - person iaforek; 17.06.2016
comment
В этом и других подобных ответах будет сказано, что первый пример в исходном вопросе ЯВЛЯЕТСЯ числом, потому что один из его символов является числом. Что если вы хотите знать, что ВСЕ символы являются числами. - person RosieC; 08.11.2016
comment
@RosieC - нет, пример в моем коде, not Value like '%[^0-9]%', точно таков, что все символы являются цифрами. Это двойной минус. Он утверждает, что ни один символ в Value не находится за пределами диапазона 0-9. - person Damien_The_Unbeliever; 08.11.2016
comment
@RosieC - или, другими словами, Value like '%[0-9]%' будет строкой, содержащей хотя бы один цифровой символ. Value like '%[^0-9]%' будет означать, что строка содержит хотя бы один нецифровой символ. Но, опять же, мой тест - not Value like '%[^0-9]%', который отрицает предыдущий тест, и строка не содержит нецифровых символов. - person Damien_The_Unbeliever; 08.11.2016

можно так проверить

declare @vchar varchar(50)
set @vchar ='34343';
select case when @vchar not like '%[^0-9]%' then 'Number' else 'Not a Number' end
person Binil    schedule 05.01.2011

Используя SQL Server 2012+, вы можете использовать функции TRY_*, если у вас есть особые потребности. Например,

-- will fail for decimal values, but allow negative values
TRY_CAST(@value AS INT) IS NOT NULL 

-- will fail for non-positive integers; can be used with other examples below as well, or reversed if only negative desired
TRY_CAST(@value AS INT) > 0

-- will fail if a $ is used, but allow decimals to the specified precision
TRY_CAST(@value AS DECIMAL(10,2)) IS NOT NULL 

-- will allow valid currency
TRY_CAST(@value AS MONEY) IS NOT NULL  

-- will allow scientific notation to be used like 1.7E+3
TRY_CAST(@value AS FLOAT) IS NOT NULL 
person Dan Field    schedule 18.03.2016
comment
Это лучшее решение. Решения, использующие %[^0-9.]%, кажется, возвращают, говоря, что это число, когда оно содержит число, даже если в строке также есть символы. Этот TRY_CAST работает для меня. - person RosieC; 08.11.2016
comment
Просто имейте в виду, что для этого требуется SQL Server 2012+ — он не будет работать на 2008R2 или ниже и не будет работать в других СУБД. - person Dan Field; 08.11.2016

Я столкнулся с необходимостью разрешить десятичные значения, поэтому я использовал not Value like '%[^0-9.]%'

person Wade73    schedule 01.12.2014

Ответ Wade73 для десятичных знаков не совсем работает. Я изменил его, чтобы разрешить только одну десятичную точку.

declare @MyTable table(MyVar nvarchar(10));
insert into @MyTable (MyVar) 
values 
    (N'1234')
    , (N'000005')
    , (N'1,000')
    , (N'293.8457')
    , (N'x')
    , (N'+')
    , (N'293.8457.')
    , (N'......');

-- This shows that Wade73's answer allows some non-numeric values to slip through.
select * from (
    select 
        MyVar
        , case when MyVar not like N'%[^0-9.]%' then 1 else 0 end as IsNumber 
    from 
        @MyTable
) t order by IsNumber;

-- Notice the addition of "and MyVar not like N'%.%.%'".
select * from (
    select 
        MyVar
        , case when MyVar not like N'%[^0-9.]%' and MyVar not like N'%.%.%' then 1 else 0 end as IsNumber 
    from 
        @MyTable
) t 
order by IsNumber;
person neizan    schedule 13.11.2015
comment
И мне пришлось добавить ‹› '.' К счастью, ни в одном из моих данных нет "-" в неправильном месте. - person Colin; 20.11.2015

Damien_The_Unbeliever отметил, что он хорош только для цифр

Wade73 добавил немного для обработки десятичных точек

neizan сделал дополнительную настройку, чего не делал

К сожалению, ни один из них не обрабатывает отрицательные значения, и у них есть проблемы с запятой в значении...

Вот моя настройка для подбора отрицательных значений и значений с запятыми

declare @MyTable table(MyVar nvarchar(10));
insert into @MyTable (MyVar) 
values 
(N'1234')
, (N'000005')
, (N'1,000')
, (N'293.8457')
, (N'x')
, (N'+')
, (N'293.8457.')
, (N'......')
, (N'.')
, (N'-375.4')
, (N'-00003')
, (N'-2,000')
, (N'3-3')
, (N'3000-')
;

-- This shows that Neizan's answer allows "." to slip through.
select * from (
select 
    MyVar
    , case when MyVar not like N'%[^0-9.]%' then 1 else 0 end as IsNumber 
from 
    @MyTable
) t order by IsNumber;

-- Notice the addition of "and MyVar not like '.'".
select * from (
select 
    MyVar
    , case when MyVar not like N'%[^0-9.]%' and MyVar not like N'%.%.%' and MyVar not like '.' then 1 else 0 end as IsNumber 
from 
    @MyTable
) t 
order by IsNumber;

--Trying to tweak for negative values and the comma
--Modified when comparison
select * from (
select 
    MyVar
    , case 
        when MyVar not like N'%[^0-9.,-]%' and MyVar not like '.' and isnumeric(MyVar) = 1 then 1
        else 0 
    end as IsNumber 
from 
    @MyTable
) t 
order by IsNumber;
person M McDonald    schedule 09.02.2017

Код Нейзан допускает значения только "." через. Рискуя стать слишком педантичным, я добавил еще одно предложение AND.

declare @MyTable table(MyVar nvarchar(10));
insert into @MyTable (MyVar) 
values 
    (N'1234')
    , (N'000005')
    , (N'1,000')
    , (N'293.8457')
    , (N'x')
    , (N'+')
    , (N'293.8457.')
    , (N'......')
    , (N'.')
    ;

-- This shows that Neizan's answer allows "." to slip through.
select * from (
    select 
        MyVar
        , case when MyVar not like N'%[^0-9.]%' then 1 else 0 end as IsNumber 
    from 
        @MyTable
) t order by IsNumber;

-- Notice the addition of "and MyVar not like '.'".
select * from (
    select 
        MyVar
        , case when MyVar not like N'%[^0-9.]%' and MyVar not like N'%.%.%' and MyVar not like '.' then 1 else 0 end as IsNumber 
    from 
        @MyTable
) t 
order by IsNumber;
person notwhereuareat    schedule 17.02.2016

Не забудьте исключить из ваших данных возврат каретки!!!

as in:

SELECT 
  Myotherval
  , CASE WHEN TRIM(REPLACE([MyVal], char(13) + char(10), '')) not like '%[^0-9]%' and RTRIM(REPLACE([MyVal], char(13) + char(10), '')) not like '.' and isnumeric(REPLACE([MyVal], char(13) + char(10), '')) = 1 THEN 'my number: ' +  [MyVal]
             ELSE ISNULL(Cast([MyVal] AS VARCHAR(8000)), '')
        END AS 'MyVal'
FROM MyTable
person Mario Levesque    schedule 18.11.2019