【问题标题】:SSIS data conversion issue of decimalSSIS数据转换十进制问题
【发布时间】:2019-05-03 13:35:11
【问题描述】:

我在我们的 SQL 服务器 (2016 SP2 CU6) 上的 SSIS 中运行了一个 dtsx 包,它是将 Excel (xlsx) 工作表按原样导入 SQL 表中的轻量级任务,在这个阶段不需要转换,有是一个代理工作,它围绕它做更多的事情,但我可以看到错误发生在这一部分。

我看到的问题是 Excel 中的数字 (0.0153) 在 SQL 中出现,好像转换错误 (1.5299999999999999E-2)。

要确认 Excel 中的数字是 0.0153,而不是更长的数字或格式如下所示。

导入后这是我所拥有的:-

我觉得这很奇怪:-

  • 他们的处境非常相似,但结果却不同
  • 它们在 Excel 工作表中一个接一个
  • 它们位于工作表顶部附近(第 10 行和第 11 行),因此如果发生类似情况,采样应该使用它们来了解数据类型(第 1 行是0.193841,这也是相似的,总体范围是-29 到 200,最多 7 位小数)
  • 它们之间只有 0.0021 的差异

Excel中的数字格式为General,SQL中的列为NVARCHAR(255)

在 SSIS 包中,External Column 的 Excel 源数据类型被归类为 double-precision float [DT-R8](不确定它来自哪里,但我无法更改它)和 输出列Unicode string [DT-WSTR]

然后我使用Native OLE DB\SQL Server Native Client 11.0 OLD DB Connection 到达餐桌。

它是一个简单的包,但为什么这个值会如此疯狂地跳跃。它不是一次性的,输入有大约 1700 行,我们在许多行上看到了这一点。

【问题讨论】:

  • 您的数据库中SBU_ANAL_FIELD_5 列的数据类型是什么?为什么将数据类型更改为DT_WSTR,而它是一个数值?
  • 科学记数法并不意味着它被“糟糕”地转换了。无论如何,为什么要将数字存储为字符串?
  • Excel 使用浮点数存储数字,0.0153 无法准确表示。 Excel 肯定会尽其所能假装这是一个精确值,但事实并非如此。除非您的列实际上是文本(即生成值的表达式是 "0.0153"),否则您将获得一个浮点数,您可以将其舍入到所需的精度,或者使用 FLOAT 类型目标列,以便此舍入可以进一步推迟到客户端处理它时。
  • 当我读到“导入 Excel 电子表格的轻量级任务”时,我笑出声来。如果可以的话,首先将其保存为管道或制表符分隔文件,这样您的头痛就会减少 100%。这是我能在这里提供的最好建议。尝试从 Excel 中提取数据时有一千个“陷阱”。 Excel 不是一个可行的数据源。
  • @JeroenMostert,是的,IMEX=1 可以在这里提供帮助,但需要记住的是,使用它本质上是在用一堆蛇换另一个,不同但不是更令人愉快的蛇。特别是,任何类型的单元格格式都将进入临时表 - 想想国家特定的货币符号、千位分隔符、会计格式,你可以命名它。

标签: sql sql-server ssis


【解决方案1】:

在企业环境中,我们不能总是选择源数据和目标数据,有时我们只需要“让它发挥作用”。 Excel 尤其是 SSIS 中的噩梦,只需对输入文件进行一次错误更改,您的工作就会失败,因为元数据不再匹配。

是的,理想情况下这是数字数据,应该存储在数字数据字段(而不是字符串/字符字段)中。

这就是我过去完成此方案的方式,希望它适用于您的情况,但实际上取决于生成的数据将用于什么。

  1. 在数据流任务中添加数据转换步骤,将双精度浮点值转换为小数(我使用了 scale=10)

2. 添加第二个数据转换步骤,将十进制值转换回 Unicode 字符串

3. 更改您的 OLE DB 目标映射以使用来自第二个数据转换任务的新输出列。

结果:

【讨论】:

  • 我可以就我的最终解决方案写一份文件,但要连同浮点 cmets 一起回答(虽然我觉得有些脾气暴躁)让我到达那里(并且教育了我!)。跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-03
  • 2011-11-27
  • 2011-12-25
  • 1970-01-01
  • 1970-01-01
  • 2013-05-22
相关资源
最近更新 更多