Die ISNUMERIC
Funktion hat ein unerwartetes Verhalten. In der MSDN-Dokumentation heißt es:
ISNUMERIC
Gibt 1 zurück, wenn der Eingabeausdruck einen gültigen numerischen Datentyp ergibt. Andernfalls wird 0 zurückgegeben. Zu den gültigen numerischen Datentypen gehören: int, bigint, smallint, tinyint, decimal, numerisch, money, smallmoney, float, real .
Und es hat auch eine Fußnote:
ISNUMERIC
Gibt 1 für einige Zeichen zurück, die keine Zahlen sind, z. B. Plus (+), Minus (-) und gültige Währungssymbole wie das Dollarzeichen ($). Eine vollständige Liste der Währungssymbole finden Sie unter Geld und Kleingeld (Transact-SQL) .
Okay, also +
, -
und aufgelistete Währungssymbole werden voraussichtlich als numerisch betrachtet. So weit, ist es gut.
Nun zum merkwürdigen Teil. Erstens sind einige der Währungssymbole aus verknüpften Artikeln nicht numerisch, einschließlich:
- Euro-Währungszeichen, hex 20A0:
₠
- Naira-Zeichen, Hex 20A6:
₦
- Rial Zeichen hex FDFC:
﷼
Das ist komisch, und ich kann nicht herausfinden, warum? Ist diese Version oder Umgebung abhängig?
Es wird jedoch seltsamer. Hier sind ein paar andere, die ich nicht erklären kann:
/
ist nicht numerisch, ist aber\
( Huh ?! )REPLICATE(N'9', 308)
ist numerisch, ist es aberREPLICATE(N'9', 309)
nicht
Die erste und grundlegendste Frage lautet: Was erklärt die obigen Fälle? Wichtiger jedoch: Welche Logik steckt dahinterISNUMERIC
, sodass ich alle Fälle selbst erklären / vorhersagen kann?
Hier ist ein guter Weg, um Dinge zu reproduzieren:
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;
Wenn ich dies auf meiner lokalen SQL Server 2012-Box ausführe, erhalte ich die folgenden Ergebnisse:
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
quelle
0
fünf der Werte angegeben werden, für die tatsächlich ein Fehler vorliegtmoney
. Die anderen scheinen genau zu sein. SQL FIDDLENCHAR(0) - NCHAR(65535)
sehe ich 112 Unstimmigkeiten. Einschließlich Zeichen,₁,₂,₃,4,5,6,7,8,9
die numerisch aussehen, aber für mich nicht erfolgreich umgewandelt werden. FiddleAntworten:
Die detaillierten Verhaltensweisen von
ISNUMERIC
sind nicht dokumentiert und wahrscheinlich niemandem ohne Quellcode-Zugriff vollständig bekannt. Das heißt, es kann sein, dass die Interpretation von der Unicode-Kategorisierung abhängt (numerisch oder nicht). Ebenso können die seltsamen Fälle, die Sie erwähnen, Fehler sein, die aus Gründen der Abwärtskompatibilität beibehalten werden. Ja, ich weiß, das klingt verrückt, aber es passiert.Da Sie SQL Server 2012 verwenden, ist dies nicht erforderlich
ISNUMERIC
. Verwenden SieTRY_CONVERT
oder auchTRY_CAST
, um zu überprüfen, ob eine Zeichenfolge in einen bestimmten Typ konvertierbar ist. Sofern sie eine ausreichende Funktionalität bieten, sind diese vorzuziehenTRY_PARSE
, da letztere eine teurere Verarbeitung über die CLR-Integration beinhaltet.quelle
Der ASCII-umgekehrte Schrägstrich (Codepunkt 5C) hat denselben Codepunkt wie das Yen-Zeichen (¥) in der von der japanischen Windows-Version verwendeten Shift-JIS-Codierung und das Won-Zeichen (₩) in der koreanischen EUC-KR. Daher ist es sehr wahrscheinlich nur eine Fortsetzung des Währungszeichenthemas.
quelle
money
dass es auch wirkt.C:¥Program Files¥