web-dev-qa-db-fra.com

Vérifier si un varchar est un nombre (SQL)

existe-t-il un moyen facile de déterminer si un varchar est un nombre?

Exemples:

abc123 -> pas de numéro

123 -> oui, c'est un numéro

Merci :)

56
grady

ISNUMERIC fera

Consultez également la section NOTES dans l'article.

30
Sachin Shanbhag

ISNUMERIC ne le fera pas - il vous indique que la chaîne peut être convertie en tout type des types numériques, ce qui est presque toujours une information inutile à connaître. Par exemple, tous les éléments suivants sont numériques, selon ISNUMERIC:

£, $, 0d0

Si vous souhaitez rechercher des chiffres et uniquement des chiffres, vous souhaitez une expression LIKE négative:

not Value like '%[^0-9]%'
130

tu peux vérifier comme ça

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

À l'aide de SQL Server 2012+, vous pouvez utiliser les fonctions TRY_ * si vous avez des besoins spécifiques. Par exemple,

-- 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 
17
Dan Field

J'ai rencontré le besoin d'autoriser les valeurs décimales, alors j'ai utilisé not Value like '%[^0-9.]%'

8
Wade73

La réponse de Wade73 pour les nombres décimaux ne fonctionne pas tout à fait. Je l'ai modifié pour ne permettre qu'un seul point décimal.

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;
3
neizan
DECLARE @A nvarchar(100) = '12'
IF(ISNUMERIC(@A) = 1)
BEGIN
    PRINT 'YES NUMERIC'
END
1
Abhishek Jaiswal

Le code de Neizan laisse des valeurs d'un "." à travers. Au risque de devenir trop pédant, j'ai ajouté une autre clause 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;
1
notwhereuareat

Damien_The_Unbeliever a noté que ce n'était que bon pour les chiffres

Wade73 a ajouté un peu pour gérer les points décimaux

neizan a fait un tweak supplémentaire, comme l'a fait le reste

Malheureusement, aucun ne semble gérer les valeurs négatives et ils semblent avoir des problèmes avec une virgule dans la valeur ...

Voici mon Tweak pour relever les valeurs négatives et celles avec des virgules

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;
1
M McDonald