SQL IsNumeric返回True但SQL报告的转换失败'

时间:2009-02-20 15:48:44

标签: sql sql-server tsql

假设以下数据:

Column1 (data type: varchar(50))
--------
11.6
-1
1,000
10"    
Non-Numeric String

我有一个查询,它从此列中提取数据,并希望确定该值是否为数字,然后在我的查询中将其返回。所以我正在做以下

SELECT CASE
       WHEN IsNumeric(Replace(Column1, '"', '')) = 1 THEN Replace(Column1, '"', '')
       ELSE 0
   END AS NumericValue

SQL正在报告:

  

将varchar值'11 .6'转换为数据类型int时,转换失败。

为什么呢?我也试图强迫这个:

SELECT CASE
       WHEN IsNumeric(Replace(Column1, '"', '')) = 1 THEN cast(Replace(Column1, '"', '') AS float)
       ELSE 0
   END AS NumericValue

我得到了:

  

将数据类型varchar转换为float时出错。

8 个答案:

答案 0 :(得分:11)

您需要用句点替换逗号:

CAST(REPLACE(column, ',', '.') AS FLOAT)

SQL Server输出使用locale定义的小数分隔符,但不会将CAST s中的句点除以数字类型之外的任何内容。

答案 1 :(得分:5)

首先将字符串转换为money,然后将其转换为任何其他数字格式,因为money类型始终提供真正的数字字符串。那时你永远不会看到错误。

在您的查询中尝试以下操作,您就会知道我在说什么。两者都将返回2345.5656。 Money数据类型舍入到4个小数位,因此转换会导致舍入到4个小数位。

SELECT CAST('2,345.56556' as money), CAST('$2,345.56556' as money)

施放(施放('2,344'作为钱)作为浮动)将完美或 施放(施放('2,344'作为金钱)作为小数(7,2))也将起作用。

甚至施放(CAST('$ 2,345.56556'作为货币)作为int)将完美地将其四舍五入到最接近的整数。

答案 2 :(得分:3)

SQL isnumeric存在许多问题。例如:

select isnumeric('1e5')

这将返回1但是在许多语言中如果您尝试将其转换为数字,则会失败。更好的方法是使用您需要检查的参数创建自己的用户定义函数:

http://www.tek-tips.com/faqs.cfm?fid=6423

答案 3 :(得分:1)

当输入表达式求值为有效整数,浮点数,货币或小数类型时,ISNUMERIC返回1;

所以问题是它是一个有效的数字,但不是一个有效的int。

答案 4 :(得分:1)

凯尔,

我认为这解决了这个问题。问题在于ELSE子句将结果初始化为INTEGER。通过对FLOAT进行明确的类型转换并添加Quassnoi的建议,它似乎有效。

DECLARE @MyTable TABLE (Column1 VARCHAR(50))
INSERT INTO @MyTable VALUES('11.6')
INSERT INTO @MyTable VALUES('-1')
INSERT INTO @MyTable VALUES('1,000')
INSERT INTO @MyTable VALUES('10"    ')
INSERT INTO @MyTable VALUES('Non-Numeric String')

SELECT CASE WHEN ISNUMERIC(REPLACE(Column1,'"','')) = 1 THEN REPLACE(REPLACE(Column1,'"',''), ',', '.') ELSE CAST(0 AS FLOAT) END
FROM @MyTable

的问候,
利芬

答案 5 :(得分:1)

IsNumeric(' ')也返回1,但随后CAST作为int爆炸。上面的Brendan说你自己写的功能。他是对的。

答案 6 :(得分:0)

此解决方案并非在所有情况下都有效(特别是有钱和/或千位分隔符的数字)。将指数表示连接到由字符串表示的数字的末尾... ISNUMERIC()从那里工作正常。以下示例:

-- CURRENT ISNUMERIC RESULTS
SELECT ISNUMERIC('11.6'); --1
SELECT ISNUMERIC ('-1'); --1
SELECT ISNUMERIC('1,000'); --1
SELECT ISNUMERIC('10"'); --0
SELECT ISNUMERIC('$10'); --1

-- NEW ISNUMERIC RESULTS
SELECT ISNUMERIC('11.6'+'e+00'); --1
SELECT ISNUMERIC ('-1'+'e+00'); --1
SELECT ISNUMERIC('1,000'+'e+00'); --0
SELECT ISNUMERIC('10"'+'e+00'); --0
SELECT ISNUMERIC('$10'+'e+00'); --0

这至少标准化了使用REPLACE()函数的格式。

答案 7 :(得分:0)

我刚刚遇到这个问题。

如果您不介意限制小数长度,可以试试这个解决方案。

CONVERT(numeric, CONVERT(money, '.')) 

注意:

  1. SQL Server 2008 或以上支持
  2. 货币范围为:-922,337,203,685,477.5808至922,337,203,685,477.5807 - 四位小数