2010-12-13 32 views
7

Une idée de pourquoi ISNUMERIC('0D0') = 1 est TRUE dans SQL Server 2008?Pourquoi "0D0" est-il considéré comme numérique dans SQL Server 2008?

Je valide les numéros d'identification d'un autre système, qui contient parfois des lettres que nous ne voulons pas apporter, mais cette combinaison est en train de trier le code (l'ID spécifique qu'il pense numérique est "005406257D6") . En aval nous faisons CONVERT(BIGINT, @val), ce qui est évidemment étouffant quand il trouve ces valeurs "D".

Quel cas particulier suis-je en train de rencontrer, et comment le comptabiliser?

+0

+1 - On dirait qu'il fonctionne aussi pour 'E', mais pas pour AC (donc ce n'est pas une chose HEX) ... – JNK

+0

Voir aussi http://stackoverflow.com/questions/2358147/best-equivalent-for-isinteger-in-sql-server la réponse par gbn est intéressant et mérite d'être essayé OMI .. –

+0

@JNK afaik "D" signifie Decimal. –

Répondre

11

Fondamentalement, IsNumeric est inutile - tout ce qu'il vérifie est que la chaîne peut être convertie en des types numériques. Dans ce cas, "0D0" peut être converti en un flottant. (Je ne me souviens pas la raison, mais efficace "D" est synonyme de "E", et signifie qu'il est la notation scientifique):

select CONVERT(float,'2D3') 

Si vous voulez vérifier que c'est juste des chiffres, alors not @val like '%[^0-9]%' serait un meilleur test. Vous pouvez améliorer cela en ajoutant un contrôle de longueur aussi.

+0

En fait, "0D0" LIKE '% [^ 0-9]%' est VRAI aussi, mais je vois ce que vous voulez dire. – gfrizzle

+0

@gfrizzle - vous avez raté le 'non' au début –

+0

@gfrizzle - vous devez faire un 'NOT LIKE' sur cette expression car il a le'^'au début indiquant NOT. C'est à dire. vous demandez "N'est-ce pas tous les numéros?" – JNK

0

Une bonne explication du pourquoi.

http://www.sqlservercentral.com/articles/IsNumeric/71512/

(ci-dessous est @ requête plus exhaustive/liste RedFilter)

SELECT [Ascii Code] = STR(Number) 
     ,[Ascii Character] = CHAR(Number) 
     ,[ISNUMERIC Returns] = ISNUMERIC(CHAR(Number)) 
FROM Master.dbo.spt_Values 
WHERE Type = 'P' 
     AND Number BETWEEN 0 AND 255 
     AND ISNUMERIC(CHAR(Number)) = 1 
UNION 
SELECT [Ascii Code] = STR(Number) 
     ,[Ascii Character] = CHAR(Number) 
     ,[ISNUMERIC Returns] = ISNUMERIC('0' + CHAR(Number) + '0') 
FROM Master.dbo.spt_Values 
WHERE Type = 'P' 
     AND Number BETWEEN 0 AND 255 
     AND ISNUMERIC('0' + CHAR(Number) + '0') = 1 

yeilds

Ascii Code Ascii Character 
---------- --------------- 
    0  
    9  
    10  
    11  
    12  
    13  
    36 $ 
    43 + 
    44 , 
    45 - 
    46 . 
    48 0 
    49 1 
    50 2 
    51 3 
    52 4 
    53 5 
    54 6 
    55 7 
    56 8 
    57 9 
    68 D 
    69 E 
    92 \ 
    100 d 
    101 e 
    128 € 
    160   
    162 ¢ 
    163 £ 
    164 ¤ 
    165 ¥ 
+0

En fait, il devrait être 'SELECT [Ascii Code] = STR (nombre), [Caractère ASCII] = CHAR (nombre), [ISNUMERIC renvoie] = ISNUMERIC (CHAR (nombre)) FROM Master.dbo. spt_values ​​ où type = 'P' ET nombre entre 0 et 255 ET ISNUMERIC (CHAR (Number)) = 1 union SELECT [code Ascii] = STR (Number), [Ascii caractères] = CHAR (Nombre) , [retour ISNUMERIC] = ISNUMERIC ('0' + CHAR (nombre) + '0') DE Master.dbo.spt_Values ​​ OU type = 'P' ET nombre entre 0 et 255 ET ISNUMERIC ('0' + CHAR (Nombre) + '0') = 1' – RedFilter

+0

Merci @RedFilter, je viens de copier/coller de l'article (puisque le site nécessite une inscription pour le voir). J'ai intégré votre mise à jour. – Brad