Các ISNUMERIC
chức năng có một số hành vi bất ngờ. Tài liệu MSDN cho biết:
ISNUMERIC
trả về 1 khi biểu thức đầu vào ước tính thành kiểu dữ liệu số hợp lệ; mặt khác, nó trả về 0. Các loại dữ liệu số hợp lệ bao gồm: int, bigint, smallint, tinyint, binary, number, money, smallmoney, float, real .
Và nó cũng có một chú thích:
ISNUMERIC
trả về 1 cho một số ký tự không phải là số, chẳng hạn như dấu cộng (+), dấu trừ (-) và ký hiệu tiền tệ hợp lệ, chẳng hạn như ký hiệu đô la ($). Để biết danh sách đầy đủ các ký hiệu tiền tệ, hãy xem tiền và smallmoney (Transact-SQL) .
Được rồi, vì vậy +
, -
và các biểu tượng tiền tệ được liệt kê dự kiến sẽ được coi là số. Càng xa càng tốt.
Bây giờ cho phần lẻ. Trước tiên, một số ký hiệu tiền tệ từ bài viết được liên kết không phải là số, bao gồm:
- Ký hiệu tiền tệ Euro, hex 20A0:
₠
- Dấu hiệu Naira, hex 20A6:
₦
- Dấu hiệu Rial, hex FDFC:
﷼
Điều này thật kỳ lạ và dường như tôi không thể tìm hiểu tại sao? Là phiên bản này hoặc môi trường phụ thuộc?
Tuy nhiên, mọi thứ trở nên kỳ lạ hơn. Dưới đây là một vài điều khác tôi không thể giải thích:
/
không phải là số, mà\
là ( Huh?! )REPLICATE(N'9', 308)
là số, nhưngREPLICATE(N'9', 309)
không phải là
Câu hỏi đầu tiên và cơ bản nhất là: điều gì giải thích các trường hợp trên? Quan trọng hơn mặc dù: logic đằng sau là gìISNUMERIC
, vì vậy tôi có thể tự mình giải thích / dự đoán tất cả các trường hợp?
Đây là một cách tốt để tái tạo mọi thứ:
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;
Khi tôi chạy nó trên hộp Sql Server 2012 cục bộ của tôi, tôi nhận được các kết quả sau:
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
NCHAR(0) - NCHAR(65535)
tôi thấy 112 sự khác biệt. Bao gồm các ký tự ₁,₂,₃,4,5,6,7,8,9
trông giống số nhưng không thể tạo thành công bất cứ thứ gì cho tôi. Fiddle
0
cho năm trong số các giá trị thực sự phù hợpmoney
. Những người khác có vẻ chính xác. FIDDLE SQL