使用SSIS导入无唯一列Excel数据到SQL Server的行标识方案咨询
解决方案总览
以下提供两种长期稳定的可落地方案,均能生成可复现的重复行次序标记,避免重复导入问题:
方案1:SSIS C#脚本组件实现(数据流层处理)
适合数据量中等、希望把逻辑封装在SSIS包内的场景:
- 在SSIS数据流的源组件读取完SharePoint表格数据后,新增脚本转换组件
- 输入列选中所有用于标识重复类别的字段,新增输出列
UniqueKey,类型设置为长度足够的字符串 - 编辑C#脚本,通过字典缓存同一类重复数据的出现次数,示例代码如下:
// 脚本类全局变量 private Dictionary<string, int> keyCounter = new Dictionary<string, int>(); public override void Input0_ProcessInputRow(Input0Buffer Row) { // 拼接复合键,用|做分隔符避免字段值本身含下划线导致冲突,统一处理null值 string compositeKey = string.Join("|", new object[] { Row.Col1, Row.Col2, Row.Col3 }.Select(x => x?.ToString() ?? "NULL_PLACEHOLDER")); if (!keyCounter.ContainsKey(compositeKey)) { keyCounter[compositeKey] = 1; } else { keyCounter[compositeKey]++; } // 生成最终唯一键,序号固定补4位保证排序一致性 Row.UniqueKey = $"{compositeKey}_{keyCounter[compositeKey].ToString("D4")}"; }
- 优势:无需修改数据库表结构,同一份源文件多次读取生成的唯一键完全一致,逻辑可控
方案2:数据库服务端实现(导入后处理)
适合数据量较大、希望利用数据库性能优化的场景:
- 目标表新增两个字段:
CompositeHash(二进制(32),存复合键的SHA256哈希值)、OccurrenceSeq(int类型,存出现次序),设置(CompositeHash, OccurrenceSeq)为联合主键 - SSIS每次导入先把全量数据写入无主键约束的临时表
- 执行SQL生成次序并做去重插入,示例代码如下:
WITH ranked_data AS ( SELECT *, -- 生成复合键哈希值 HASHBYTES('SHA2_256', CONCAT_WS('|', ISNULL(Col1,''), ISNULL(Col2,''), ISNULL(Col3,''))) AS CompositeHash, -- 统计同一类数据的出现次序 ROW_NUMBER() OVER(PARTITION BY CONCAT_WS('|', ISNULL(Col1,''), ISNULL(Col2,''), ISNULL(Col3,'')) ORDER BY (SELECT 1)) AS OccurrenceSeq FROM 导入临时表名 ) INSERT INTO 目标表名 (所有业务字段名, CompositeHash, OccurrenceSeq) SELECT 所有业务字段名, CompositeHash, OccurrenceSeq FROM ranked_data t WHERE NOT EXISTS ( SELECT 1 FROM 目标表名 d WHERE d.CompositeHash = t.CompositeHash AND d.OccurrenceSeq = t.OccurrenceSeq );
- 优势:数据库原生窗口函数性能远高于SSIS脚本处理,哈希值代替长字符串拼接的联合键占用存储空间更小,去重逻辑更简单
通用注意事项
- 拼接复合键时必须处理null值,避免不同数据因为null拼接后结果相同
- 分隔符建议选用源数据中不会出现的特殊字符,避免字段值本身包含分隔符导致的键冲突
- 两种方案生成的次序仅对同一份源文件可复现,只要源文件内容不变,多次导入不会生成重复数据
内容的提问来源于stack exchange,提问作者Tim Palacios
相关产品推荐
相关产品推荐

