Je dois vérifier une colonne numérique ou non dans SQL Server 2012.
C'est mon code de cas.
CASE
WHEN ISNUMERIC(CUST_TELE) = 1
THEN CUST_TELE
ELSE NULL
END AS CUSTOMER_CONTACT_NO
Mais lorsque la valeur '78603D99'
est atteinte, il renvoie 1
, ce qui signifie que SQL Server a considéré cette chaîne comme numérique.
Pourquoi donc?
Comment éviter ce genre de problèmes?
Malheureusement, la fonction ISNUMERIC()
dans SQL Server présente de nombreux défauts. Ce n'est pas vraiment un buggy, mais il fait rarement ce que les gens attendent quand ils l'utilisent pour la première fois.
Cependant, puisque vous utilisez SQL Server 2012, vous pouvez utiliser la fonction TRY_PARSE()
qui fera ce que vous voulez.
Ceci retourne NULL: SELECT TRY_PARSE('7860D399' AS int)
Ceci retourne 7860399 SELECT TRY_PARSE('7860399' AS int)
https://msdn.Microsoft.com/en-us/library/hh213126.aspx
Évidemment, cela fonctionne pour les types de données autres que INT
. Vous dites que vous voulez vérifier qu'une valeur est numérique, mais je pense que vous voulez dire INT
.
Bien que try_convert()
ou try_parse()
fonctionne pour un type intégré, il se peut qu'il ne fasse pas exactement ce que vous voulez. Par exemple, il peut autoriser les points décimaux, les signes négatifs et limiter la longueur des chiffres.
De plus, isnumeric()
va reconnaître les nombres négatifs, les décimales et la notation exponentielle.
Si vous souhaitez tester une chaîne uniquement pour les chiffres, vous pouvez utiliser la logique not like
:
(CASE WHEN CUST_TELE NOT LIKE '%[^0-9]%'
THEN CUST_TELE
END) AS CUSTOMER_CONTACT_NO
Ceci dit simplement que CUST_TELE
ne contient aucun caractère qui ne soit pas un chiffre.
Rien de substantiel à ajouter mais quelques avertissements.
1) ISNUMERIC () n'acceptera pas les blancs mais ceux-ci interrompront les conversions numériques.
2) S'il n'y a qu'un seul caractère non numérique dans le champ et que vous utilisez REPLACE pour vous en débarrasser, vous devez toujours gérer le blanc (généralement avec une instruction CASE).
Par exemple, si le champ contient un seul caractère '-' et que vous l'utilisez:
cast(REPLACE(myField, '-', '') as decimal(20,4)) myNumField
cela échouera et vous devrez utiliser quelque chose comme ceci:
CASE WHEN myField IN ('','-') THEN NULL ELSE cast(REPLACE(myField, '-', '') as decimal(20,4)) END myNumField