【问题标题】:SQL : Error converting data type nvarchar to floatSQL:将数据类型 nvarchar 转换为浮点数时出错
【发布时间】:2017-06-05 20:55:01
【问题描述】:

我想将nvarchar数据转换为float类型。

就我而言,我有SalesValue 列,我使用了这个命令

UPDATE Overseas 
SET SalesValue = CONVERT(FLOAT, REPLACE([SalesValue],',','') )

我的表有类似的值

201.01
40.50
215.12
550
304.201

但我得到一个错误

SQL : 将数据类型 nvarchar 转换为浮点数时出错。

我该如何解决这个问题?

【问题讨论】:

  • 这些钱是多少?不建议一开始就使用 FLOAT。使用 DECIMAL 或 MONEY。问题不在于您作为示例提供的十进制值。它将使用无法转换为小数的值(如美元符号 $)。
  • 这些值都可以转换为浮点数据类型。 SELECT CAST('201.01' AS FLOAT) SELECT CAST('40.50' AS FLOAT) SELECT CAST('215.12' AS FLOAT) SELECT CAST('550' AS FLOAT) SELECT CAST('304.201' AS FLOAT)
  • 还有其他事情吗?
  • 是的货币价格
  • @Tarzan 我举个例子我希望这个表中的所有数据都转换为浮点数

标签: sql sql-server-2008


【解决方案1】:

您应该找到不匹配的值。在 SQL Server 2012+ 中,您可以使用 try_convert()。那是不可用的。那么,这个怎么样?

SELECT SalesValue
FROM Overseas
WHERE SalesValue LIKE '%[^0-9,.]%' OR
      SalesValue LIKE '%[.,]%[.,]%';

我认为这涵盖了明显的违规行为:不是数字的字符或两个(或更多)小数点。

【讨论】:

  • @3mr 。 . .您必须运行查询以找出错误值是什么。然后相应地处理它们。
  • 我按照你说的做了,但我通常从 excel 文件动态加载我的数据。现在需要手动将坏值放在哪里?
  • @3mr 。 . . Excel 不强制类型,因此可以导入任何内容。
  • 所以我得到了不好的价值观..然后呢?
  • @3mr 。 . .我建议您提出另一个问题并显示失败的实际值。
【解决方案2】:

使用下面的查询进行第一次转换,然后正常更新

 SELECT
          case when  ISNUMERIC([SalesValue])=1
          then CAST([SalesValue] AS FLOAT) else 0 end AS CastedValue)
      FROM your_table_name

【讨论】:

  • SalesValue = '$'SalesValue = '1e4' 中尝试您的代码。你的方法有缺陷,你会从阅读this post 和它的基础参考中受益。
【解决方案3】:

在我看来,您的数据仍然包含非数字的内容。我希望您的应用程序端在输入前清理数据方面做得很好,问题可能是您的一个或多个字段中有一个“$”。 当您有除“。”之外的非数字字符时,Cast 将失败在其中(您可能知道这就是您删除“,”的原因)。 我运行了下面的脚本来测试它。

declare @myFloat float;
declare @test1 nvarchar(10) = '145.88';
declare @test2 nvarchar(10) = '4,145.88';
declare @test3 nvarchar(10) = '$4,145.88';

SELECT ISNUMERIC(@TEST3)
set @myFloat = CONVERT(FLOAT, REPLACE(@test1,',','') );
select @myFloat;

set @myFloat = CONVERT(FLOAT, REPLACE(@test2,',','') );
select @myFloat;

--THIS WILL FAIL
set @myFloat = CONVERT(FLOAT, REPLACE(@test3,',','') );
select @myFloat;
--THIS WILL NOT FAIL
set @myFloat = CONVERT(FLOAT, REPLACE(REPLACE(@test3,',',''),'$','') );
select @myFloat;

您可以尝试在有问题的列上运行以下脚本,以查看您遇到问题的列:

--run this on your table
SELECT SalesValue
FROM Overseas
WHERE ISNUMERIC(REPLACE(SalesValue,',','')) = 0

--test sample
/*
insert into #myTable
values ('145.88'),
       ('4,145.88'),
       ('$4,145.88'),
       ('$4,145.88%'); 

SELECT *
FROM #myTable
WHERE ISNUMERIC(REPLACE(amounts,',','')) = 0 
--WHERE ISNUMERIC(REPLACE(REPLACE(amounts,',',''),'$','')) = 0 --this will remove results with $ also
*/

所以您的解决方法是简单地将您提供的行更改为:

UPDATE Overseas SET SalesValue = CONVERT(FLOAT, REPLACE(REPLACE([SalesValue],',',''),'$','') )

除非您在先前脚本的结果中找到其他字符。

【讨论】:

  • 我没有像我说的那样在我的值上签名 .. 我从 excel 表中获取了我的数据,我认为这是问题所在..
  • 用科学记数法检查你的代码...即'1e4' as @test
  • 我同意 scsimon。 Excel 尝试通过根据列数据的抽样确定数据类型来“提供帮助”。在我的工作中,我有一个 SSIS 包,可以查看 excel 文档中的单元格。我在测试和生产中发现,当工作簿没有为所有单元格预先格式化为“文本”时,或者如果您从另一个来源复制和粘贴(编码问题),我的包将无法正确读取数据。 @3mr todo:获取一个空白工作簿,全选,将单元格格式化为文本,粘贴您的数据,然后重试。
  • @3mr,您是否曾经运行过脚本来检查数据中的任何非数字行? SELECT SalesValue AS [BAD VALUE], * FROM Overseas WHERE ISNUMERIC(REPLACE(SalesValue,',','')) = 0
【解决方案4】:

这将使您比ISNUMERIC()更接近

declare @table table (SalesValue varchar(16))
insert into @table
values
('1e4'),
('$'),
('134.55'),
('66,9897'),
('14')

select
    SalesValue
    ,case 
        when SalesValue NOT LIKE '%[^0-9,.]%' 
        then convert(decimal(16,4),replace(SalesValue,',','.'))
    end
from 
    @table

【讨论】:

    猜你喜欢
    • 2021-08-08
    • 1970-01-01
    • 2017-03-23
    • 2017-03-15
    • 2011-05-18
    • 2012-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多