La ISNUMERIC
función tiene un comportamiento inesperado. La documentación de MSDN dice:
ISNUMERIC
devuelve 1 cuando la expresión de entrada se evalúa como un tipo de datos numéricos válido; de lo contrario, devuelve 0. Los tipos de datos numéricos válidos incluyen los siguientes: int, bigint, smallint, tinyint, decimal, numérico, money, smallmoney, float, real .
Y también tiene una nota al pie:
ISNUMERIC
devuelve 1 para algunos caracteres que no son números, como más (+), menos (-) y símbolos de moneda válidos, como el signo de dólar ($). Para obtener una lista completa de los símbolos de moneda, vea money and smallmoney (Transact-SQL) .
De acuerdo, entonces +
, -
y los símbolos de moneda listados se considerarán numéricos. Hasta aquí todo bien.
Ahora para la parte extraña. En primer lugar, algunos de los símbolos de moneda del artículo vinculado no son numéricos, incluidos:
- Signo de Euro-Moneda, hex 20A0:
₠
- Signo de Naira, hex 20A6:
₦
- Signo de Rial, hex FDFC:
﷼
Esto es extraño, y parece que no puedo entender por qué. ¿Es esta versión o entorno dependiente?
Sin embargo, las cosas se ponen más raras. Aquí hay algunos otros que no puedo explicar:
/
no es numérico, pero\
es (¿ eh? )REPLICATE(N'9', 308)
es numérico, peroREPLICATE(N'9', 309)
no es
La primera y más básica pregunta es: ¿qué explica los casos anteriores? Más importante aún: ¿cuál es la lógica detrásISNUMERIC
, para poder explicar / predecir todos los casos yo mismo?
Aquí hay una buena forma de reproducir cosas:
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;
Cuando ejecuto esto en mi cuadro local de SQL Server 2012 obtengo los siguientes resultados:
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)
veo 112 discrepancias. Incluyendo personajes como los ₁,₂,₃,4,5,6,7,8,9
que parecen numéricos pero no se lanzan con éxito a nada para mí. Fiddle
0
de cinco de los valores que realmente funcionanmoney
. Los otros parecen precisos. SQL FIDDLE