2

我想将 Varchar 列中的数据转换为数字数据类型 -
所以在转换之前我调用 ISNUMERIC 函数来检查数据是否为数字,如果是则将其转换为数字数据类型。但我面临一个问题 -
IsNumeric 函数的行为不符合预期 -

- IsNumeric(x) returns true - when varchar value has both comma and a tab character (Char(9)), 
- IsNumeric(x) returns false - when varchar value has only tab character and no comma

它在以下 SQL 的帮助下进行了解释-

DECLARE @propValue AS VARCHAR(50)
SET @propValue = '1,592 ' -- contains comma + tab (Char(9))
SELECT ISNUMERIC(@propValue)  -- Returns 1 

--If ISNUMERIC func returns true for this value, lets convert this Varchar value to Numeric
SELECT CAST(@propValue AS Numeric(19, 4)) -- :-( Error converting data type varchar to numeric.

我用谷歌搜索并找到了解决这个问题的各种解决方案 -

--Solution 1: use 'e0'
SELECT ISNUMERIC(@propValue + 'e0')  -- Returns 0

--Solution 2: remove comma before calling IsNumeric()
SELECT ISNUMERIC(REPLACE(@propValue, ',', ''))  -- Returns 0

--Solution 3
--Call CLR function to parse Varchar value

在上述情况下推荐的解决方案是什么?为什么?
另外,如果有人能解释为什么 IsNumeric(x) 返回 false - 当 varchar 值只有制表符而没有逗号时,我将不胜感激?

谢谢!

4

2 回答 2

1

请记住,ISNUMERIC() = 1这并不意味着“可以转换为每种数字类型”,而是“可以转换为至少一种数字类型”。很多情况下,值可以转换为至少一种数字类型,但不是您想要的。一个更基本的例子:

IF ISNUMERIC(256) = 1
  SELECT CONVERT(TINYINT, 256);

如果您有已知违规的字符串(例如制表符),那么为什么不替换制表符呢?为什么不首先阻止垃圾数据进入这个值呢?

这有效,但它很丑陋:

DECLARE @x TABLE (propValue VARCHAR(50));

INSERT @x SELECT '1,592' + CHAR(9)
UNION ALL SELECT '55' + CHAR(9) + '32'
UNION ALL SELECT CHAR(9) + '7,452.32    '
UNION ALL SELECT 'foo'
UNION ALL SELECT '74';

SELECT CONVERT(NUMERIC(19,4), 
LTRIM(RTRIM(REPLACE(REPLACE(propValue, CHAR(9), ''), ',', '')))
)
FROM @x
WHERE ISNUMERIC(LTRIM(RTRIM(REPLACE(REPLACE(propValue, 
  CHAR(9), ''), ',', ''))) + 'e0') = 1;

虽然不适用于您的确切问题,但我在 10 年前写了一个关于此的常见问题解答:http: //classicasp.aspfaq.com/general/what-is-wrong-with-isnumeric.html

于 2012-07-02T01:59:21.027 回答
-1
ISNUMERIC(RTRIM(LTRIM(x))) = 1
于 2012-07-01T19:57:02.817 回答