La ISNUMERIC
fonction a un comportement inattendu. La documentation MSDN indique:
ISNUMERIC
renvoie 1 lorsque l'expression d'entrée est évaluée en un type de données numérique valide; sinon, il renvoie 0. Les types de données numériques valides sont les suivants: int, bigint, smallint, tinyint, decimal, numeric, money, smallmoney, float, real .
Et il a également une note de bas de page:
ISNUMERIC
renvoie 1 pour certains caractères qui ne sont pas des nombres, tels que plus (+), moins (-) et des symboles monétaires valides tels que le signe dollar ($). Pour une liste complète des symboles monétaires, consultez money and smallmoney (Transact-SQL) .
D'accord, donc +
, -
et les symboles monétaires répertoriés devraient être considérés comme numériques. Jusqu'ici tout va bien.
Maintenant pour la partie étrange. Tout d'abord, certains des symboles monétaires de l'article lié ne sont pas numériques, notamment:
- Signe euro-monnaie, hex 20A0:
₠
- Signe Naira, hex 20A6:
₦
- Signe Rial, hex FDFC:
﷼
C'est bizarre, et je n'arrive pas à découvrir pourquoi? Cette version ou l'environnement dépend-il?
Cependant, les choses deviennent plus étranges. Voici quelques autres que je ne peux pas expliquer:
/
n'est pas numérique, mais l'\
est ( Huh?! )REPLICATE(N'9', 308)
est numérique, maisREPLICATE(N'9', 309)
n'est pas
La première question, la plus fondamentale, est: qu'est-ce qui explique les cas ci-dessus? Mais plus important encore: quelle est la logique derrièreISNUMERIC
, afin que je puisse expliquer / prédire tous les cas moi-même?
Voici un bon moyen de reproduire des choses:
DECLARE @tbl TABLE(txt NVARCHAR(1000));
INSERT INTO @tbl (txt)
VALUES (N''), (N' '), (N'€'), (N'$'), (N'$$'),
(NCHAR(8356)), (NCHAR(8352)), (NCHAR(8358)), (NCHAR(65020)),
(N'+'), (N'-'), (N'/'), (N'\'), (N'_'), (N'e'), (N'1e'), (N'e1'), (N'1e1'),
(N'1'), (N'-1'), (N'+1'), (N'1+1'), (N'⒈'), (N'🄂'), (N'¹'), (N'①'), (N'½'),
(N'🎅'), (REPLICATE(N'9', 307)), (REPLICATE(N'9', 308)), (REPLICATE(N'9', 309)),
(REPLICATE(N'9', 310));
SELECT UNICODE(LEFT(txt, 1)) AS FirstCharAsInt,
LEN(txt) AS TxtLength,
txt AS Txt,
ISNUMERIC(txt) AS [ISNUMERIC]
FROM @tbl;
Lorsque j'exécute cela sur ma boîte Sql Server 2012 locale, j'obtiens les résultats suivants:
FirstCharAsInt TxtLength Txt ISNUMERIC
--------------- ---------- --------- ----------
NULL 0 0
32 0 0
8364 1 € 1
36 1 $ 1
36 2 $$ 0
8356 1 ₤ 1
8352 1 ₠ 0 --??
8358 1 ₦ 0 --??
65020 1 ﷼ 0 --??
43 1 + 1
45 1 - 1
47 1 / 0
92 1 \ 1 --??
95 1 _ 0
101 1 e 0
49 2 1e 0
101 2 e1 0
49 3 1e1 1
49 1 1 1
45 2 -1 1
43 2 +1 1
49 3 1+1 0
9352 1 ⒈ 0
55356 2 🄂 0
185 1 ¹ 0
9312 1 ① 0
189 1 ½ 0
55356 2 🎅 0
57 307 /*...*/ 1
57 308 /*...*/ 1 --??
57 309 /*...*/ 0 --??
57 310 /*...*/ 0
la source
0
cinq des valeurs qui conviennent réellementmoney
. Les autres semblent exacts. SQL FIDDLENCHAR(0) - NCHAR(65535)
je vois 112 écarts. Y compris des caractères tels que ceux₁,₂,₃,4,5,6,7,8,9
qui semblent numériques mais qui ne réussissent pas à quelque chose pour moi. ViolonRéponses:
Les comportements détaillés de
ISNUMERIC
ne sont pas documentés et ne sont probablement pas entièrement connus de quiconque sans accès au code source. Cela dit, il se peut que l'interprétation dépende de la catégorisation Unicode (numérique ou non). De même, les cas étranges que vous mentionnez peuvent être des bogues qui sont conservés pour une compatibilité descendante. Oui, je sais que cela semble fou, mais cela arrive.Comme vous utilisez SQL Server 2012, il n'est pas nécessaire de l'utiliser
ISNUMERIC
. UtilisezTRY_CONVERT
ou également à laTRY_CAST
place pour vérifier si une chaîne est convertible en un type donné. Lorsqu'elles fournissent des fonctionnalités adéquates, elles sont préférables àTRY_PARSE
, car ces dernières impliquent un traitement plus coûteux via l'intégration CLR.la source
La barre oblique inversée ASCII (point de code 5C) partage le même point de code que le signe yen (¥) dans l'encodage Shift-JIS utilisé par la version japonaise de Windows, et le signe won (₩) en coréen EUC-KR. Par conséquent, il s'agit très probablement d'une continuation du thème du signe monétaire.
la source
money
qu'il s'applique également.C:¥Program Files¥
dans explorer.exe