导入带有虚拟小数的固定宽度文件
Import fixed width file with virtual decimals
我有一个固定宽度的主数据文件。该文件包含许多带成本的列,但没有小数 point.This 数据需要导入到 SQL 服务器。
在规范文档的帮助下,我知道了那些列的精度和小数位数。
我尝试了下面的方法,并在 SSIS 2017 中尝试了其中一种方法的组合,但没有成功:
- 在 'flat file connection manager' 中设置精度和小数位数。
- 使用数据转换转换
DT_Numeric
指定精度和小数位数
我在错误路径上设置了重定向,所有行都采用该路径。
如果该值不包含小数点,则在使用派生列添加小数点之前不能将它们转换为小数。尝试以下解决方案:
假设我们有以下整数值
12301452
我们需要将其转换为十进制,如下所示:
1230.1452
然后我们应该在派生列中使用类似的表达式:
(DT_DECIMAL, 4)( SUBSTRING((DT_WSTR,50) @[User::Variable],1,LEN( (DT_WSTR,50)@[User::Variable] ) - 4) + "." + RIGHT((DT_WSTR,50)@[User::Variable],4))
其中 4
是比例值。
在处理隐含的小数位时,实际上有两种方法:字符串操作,如 Hadi 所演示的,将小数字符放入字符串中以获得显式值。
第二种方法就是用数学计算出来。
这两种方法都会导致您必须在平面文件连接管理器中定义与目标类型不同的列。将数据注入管道后,您将需要对其进行修改以满足目标类型。
如果您使用 Hadi 的解决方案,省去多次强制转换(数据类型更改)的麻烦,只需将值作为字符串导入即可。您使用派生列转换执行字符串操作,以在隐式小数位的位置拆分字符串。逻辑大约
SUBSTRING(MyColumn, 1, IntegerDigits) + "." + RIGHT(MyColumn, ScaleDigits)
其中 IntegerDigits 和 ScaleDigits 是小数点前后的位数。
我会在派生列转换中将该列称为 MyColumnWithDecimalPlace
。
然后我将在上述派生列转换之后添加第二个派生列转换(或数据转换转换)。在此步骤中,我们会将此字符串值转换为数值。为什么要分两步?如果数据有些 奇怪 ,我可以在这两个点之间放置一个数据视图(或数据抽头),然后观察哪里出了问题。如果我试图一举完成,那么我看不出是在字符串中添加一个小数位失败了,还是我刚刚构建的字符串值被破坏了,无法转换为数字。
另一种方法是将源列定义为整数之类的东西,然后使用派生列转换对其进行数学计算。那看起来像
MyColumn / POWER(10, ScaleDigits)
同样,ScaleDigits
是我们期望的小数位数。我倾向于赞成这种方法,因为它更简单 - 一次操作即可完成。
我有一个固定宽度的主数据文件。该文件包含许多带成本的列,但没有小数 point.This 数据需要导入到 SQL 服务器。
在规范文档的帮助下,我知道了那些列的精度和小数位数。
我尝试了下面的方法,并在 SSIS 2017 中尝试了其中一种方法的组合,但没有成功:
- 在 'flat file connection manager' 中设置精度和小数位数。
- 使用数据转换转换
DT_Numeric
指定精度和小数位数
我在错误路径上设置了重定向,所有行都采用该路径。
如果该值不包含小数点,则在使用派生列添加小数点之前不能将它们转换为小数。尝试以下解决方案:
假设我们有以下整数值
12301452
我们需要将其转换为十进制,如下所示:
1230.1452
然后我们应该在派生列中使用类似的表达式:
(DT_DECIMAL, 4)( SUBSTRING((DT_WSTR,50) @[User::Variable],1,LEN( (DT_WSTR,50)@[User::Variable] ) - 4) + "." + RIGHT((DT_WSTR,50)@[User::Variable],4))
其中 4
是比例值。
在处理隐含的小数位时,实际上有两种方法:字符串操作,如 Hadi 所演示的,将小数字符放入字符串中以获得显式值。
第二种方法就是用数学计算出来。
这两种方法都会导致您必须在平面文件连接管理器中定义与目标类型不同的列。将数据注入管道后,您将需要对其进行修改以满足目标类型。
如果您使用 Hadi 的解决方案,省去多次强制转换(数据类型更改)的麻烦,只需将值作为字符串导入即可。您使用派生列转换执行字符串操作,以在隐式小数位的位置拆分字符串。逻辑大约
SUBSTRING(MyColumn, 1, IntegerDigits) + "." + RIGHT(MyColumn, ScaleDigits)
其中 IntegerDigits 和 ScaleDigits 是小数点前后的位数。
我会在派生列转换中将该列称为 MyColumnWithDecimalPlace
。
然后我将在上述派生列转换之后添加第二个派生列转换(或数据转换转换)。在此步骤中,我们会将此字符串值转换为数值。为什么要分两步?如果数据有些 奇怪 ,我可以在这两个点之间放置一个数据视图(或数据抽头),然后观察哪里出了问题。如果我试图一举完成,那么我看不出是在字符串中添加一个小数位失败了,还是我刚刚构建的字符串值被破坏了,无法转换为数字。
另一种方法是将源列定义为整数之类的东西,然后使用派生列转换对其进行数学计算。那看起来像
MyColumn / POWER(10, ScaleDigits)
同样,ScaleDigits
是我们期望的小数位数。我倾向于赞成这种方法,因为它更简单 - 一次操作即可完成。