如何在SSIS中将含混合小数点的CSV价格列转为浮点数/十进制数
解决SSIS导入CSV时混合小数点格式的价格转换问题
我之前处理多区域数据源时也踩过这个坑,你的问题核心是CSV里同时存在.和,两种小数点分隔符,而SSIS的默认数据转换规则会把不匹配的分隔符当成无效字符忽略,导致小数部分被合并到整数位(比如125,60会被当成12560)。下面是几个实用的解决步骤:
步骤1:先以字符串类型导入Price列
不要一开始就把Price列设为Decimal/Money/Float,先在平面文件连接管理器里把Price列的数据类型改成string [DT_STR]或unicode string [DT_WSTR],确保原始数据完整读入SSIS,不会被提前错误转换。
方法一:使用派生列转换统一格式
通过派生列组件,先把所有价格字符串统一成一种小数点格式,再转换为数值类型:
- 先判断字符串里是否包含
,:用FINDSTRING(Price, ",", 1) > 0 - 如果包含,就把
,替换成.;如果不包含,直接保留原字符串 - 示例表达式:
注:(DT_DECIMAL, 2)(FINDSTRING(Price, ",", 1) > 0 ? REPLACE(Price, ",", ".") : Price)(DT_DECIMAL, 2)是转换为保留两位小数的Decimal类型,你可以根据需求调整精度。
方法二:使用脚本组件(应对复杂格式更灵活)
如果数据里还有更复杂的情况(比如同时存在千位分隔符,像1.234,50这种),用脚本组件处理会更稳妥:
- 在数据流中添加脚本组件,选择“转换”模式
- 把Price列作为输入列,添加一个新的输出列(比如
CleanedPrice,类型设为DT_DECIMAL) - 打开脚本编辑器,在
Input0_ProcessInputRow方法里写处理逻辑(以C#为例):public override void Input0_ProcessInputRow(Input0Buffer Row) { if (!Row.Price_IsNull && !string.IsNullOrEmpty(Row.Price)) { string priceStr = Row.Price.Trim(); // 统一替换逗号为小数点 priceStr = priceStr.Replace(",", "."); // 处理可能存在的千位分隔符(比如1.234.567,89这类格式) int lastDotIndex = priceStr.LastIndexOf('.'); if (lastDotIndex > 0) { priceStr = priceStr.Substring(0, lastDotIndex).Replace(".", "") + priceStr.Substring(lastDotIndex); } // 转换为Decimal类型 if (decimal.TryParse(priceStr, out decimal result)) { Row.CleanedPrice = result; } else { // 处理转换失败的情况,标记为NULL或设置默认值 Row.CleanedPrice_IsNull = true; } } else { Row.CleanedPrice_IsNull = true; } } - 保存脚本,运行数据流即可得到正确的数值。
方法三:修改平面文件连接管理器的区域设置(仅适用于单一分隔符场景)
如果你的CSV是来自不同区域的独立文件(每个文件只用一种分隔符),可以针对文件设置对应区域:
- 打开平面文件连接管理器的“高级”选项卡,选中Price列
- 在右侧属性里找到
LocaleID,选择对应的区域(比如用,当小数点的选“德语(德国)”,用.的选“英语(美国)”) - 注意:这个方法不适合同一个文件里同时有两种分隔符的情况,更推荐前两种方法。
最后提醒:转换后一定要抽查数据,确保转换后的数值和原始数据一致,避免因为千位分隔符的干扰出现错误。
内容的提问来源于stack exchange,提问作者FeniceFenice
相关产品推荐
相关产品推荐

