The ISNUMERIC
fungsi memiliki beberapa perilaku yang tidak diharapkan. Dokumentasi MSDN mengatakan:
ISNUMERIC
mengembalikan 1 ketika ekspresi input mengevaluasi ke tipe data numerik yang valid; selain itu mengembalikan 0. Jenis data numerik yang valid meliputi yang berikut: int, bigint, smallint, tinyint, desimal, numerik, uang, smallmoney, float, real .
Dan itu juga memiliki catatan kaki:
ISNUMERIC
mengembalikan 1 untuk beberapa karakter yang bukan angka, seperti plus (+), minus (-), dan simbol mata uang yang valid seperti tanda dolar ($). Untuk daftar lengkap simbol mata uang, lihat uang dan uang kecil (Transact-SQL) .
Oke, jadi +
,, -
dan simbol mata uang yang terdaftar diharapkan dianggap numerik. Sejauh ini baik.
Sekarang untuk bagian yang aneh. Pertama, beberapa simbol mata uang dari artikel yang ditautkan tidak berupa angka, termasuk:
- Tanda Euro-Mata Uang, hex 20A0:
₠
- Tanda Naira, hex 20A6:
₦
- Tanda Rial, hex FDFC:
﷼
Ini aneh, dan sepertinya saya tidak tahu mengapa? Apakah versi atau lingkungan ini tergantung?
Namun, hal-hal semakin aneh. Berikut beberapa hal lain yang tidak bisa saya jelaskan:
/
bukan numerik, tetapi\
apakah ( Hah ?! )REPLICATE(N'9', 308)
numerik, tetapiREPLICATE(N'9', 309)
tidak
Pertanyaan pertama dan paling mendasar adalah: apa yang menjelaskan kasus-kasus di atas? Lebih penting lagi: apa logika di baliknyaISNUMERIC
, jadi saya bisa menjelaskan / memprediksi semua kasus sendiri?
Berikut cara yang baik untuk mereproduksi sesuatu:
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;
Ketika saya menjalankan ini pada kotak Sql Server 2012 lokal saya, saya mendapatkan hasil berikut:
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
sumber
0
lima dari nilai-nilai yang benar-benar berlakumoney
. Yang lain tampak akurat. SQL FIDDLENCHAR(0) - NCHAR(65535)
saya melihat 112 perbedaan. Termasuk karakter seperti₁,₂,₃,4,5,6,7,8,9
yang terlihat numerik tetapi tidak berhasil melakukan apa pun untuk saya. FiddleJawaban:
Perilaku terperinci dari
ISNUMERIC
tidak didokumentasikan, dan mungkin tidak sepenuhnya diketahui siapa pun tanpa akses kode sumber. Yang mengatakan, mungkin interpretasi itu tergantung pada kategorisasi Unicode (numerik atau tidak). Sama halnya, kasus aneh yang Anda sebutkan mungkin berupa bug yang dipertahankan untuk kompatibilitasnya. Ya saya tahu itu terdengar gila, tetapi itu memang terjadi.Saat Anda menggunakan SQL Server 2012, tidak perlu digunakan
ISNUMERIC
. GunakanTRY_CONVERT
atau sinonimTRY_CAST
untuk memeriksa apakah string dapat dikonversi ke jenis yang diberikan. Di mana mereka menyediakan fungsionalitas yang memadai, ini lebih disukaiTRY_PARSE
, karena yang terakhir melibatkan pemrosesan yang lebih mahal melalui integrasi CLR.sumber
Garis miring terbalik ASCII (titik kode 5C) terjadi untuk berbagi titik kode yang sama dengan tanda yen (¥) dalam penyandian Shift-JIS yang digunakan oleh Windows versi Jepang, dan tanda menang (₩) dalam EUC-KR Korea. Oleh karena itu, sangat mungkin hanya kelanjutan dari tema tanda mata uang.
sumber
money
yang dilemparkan juga.C:¥Program Files¥
di explorer.exe