SSIS防止从平面文件插入SQL Server表中已经存在的数据行

时间:2018-09-15 08:05:43

标签: ssis

我需要创建一个SSIS程序包,在该程序包中,我正在读取一个平面文件(每月提供,其中包含许多已定义的列),然后将数据写入到已定义的SQL Server表中(其中很多数据已存在于SQL表中)。在SQL表设计视图中,我具有的数据类型包括float,datetime,bigint,varchar(它们已经定义并且不能更改)

我需要阻止从平面文件中SQL Server表中已经存在的任何数据行插入。如何实现此目的?

我尝试使用查找转换来实现此目的‌‌‌,但是在“编辑映射”中,创建关系时出现错误“无法映射查找列,因为该列设置为浮点数据类型”。我能够为所有其他数据类型创建关系,但是源文件中有一些数据行仅与浮点值中的sql表中的数据不同,并且期望将插入这些行。

‌还有其他简单的方法可以实现吗?

谢谢。

2 个答案:

答案 0 :(得分:0)

请尝试使用数据转换来转换在映射中有问题的列。

谢谢

答案 1 :(得分:0)

SSIS和SQL批量加载(SSIS加载任务后面的SQL功能)都不允许开箱即用。

您可以使用@sasi描述的方法,并在您的查找中使用sql cast(convert关键字)自己定义sql查询。但是,即使您可以通过这种方式解决转换问题,但如果加载大量数据,您肯定会遇到性能问题。

有两种处理方法:

第一个(与其他选项相比最简单但最安静的速度,在某些情况下甚至可能比您的解决方案还要慢),对每行使用插入语句命令和sql命令,如下所示:

INSERT target_table (val1, val2, id)  
SELECT $myVal1, $myVal2, $myCandidateKey
WHERE NOT EXISTS (SELECT 1 FROM target_table as t WHERE t.id = $myCandidateKey);  

第二个含义是在目标数据库上创建临时表。该表与目标表的结构相同。它是永久创建的。您还必须在应该是键的索引上创建索引,该键将定义记录是否已被加载。您的进程将在执行任何明显目的的操作之前将其清空。而不是使用SSIS加载目标表,而是加载此登台表。加载该临时表后,您将仅运行以下命令一次:

INSERT target_table (val1, val2, id)  
SELECT stg.val1, stg.val2, stg.id
FROM staging_target_table as stg
WHERE NOT EXISTS (SELECT 1 FROM target_table as t WHERE t.id = stg.id);

与第一个解决方案相比,这非常快。

在这种情况下,我认为允许您识别行的是键(“ id”列),但是如果您实际上想比较整行,则必须为该行添加类似的比较第一个解决方案:

INSERT target_table (val1, val2)  
SELECT $myVal1, $myVal2
WHERE NOT EXISTS (SELECT 1 FROM target_table as t WHERE t.val1 = $myVal1 and t.val2 = $myVal2);  

或在第二个解决方案中这样:

INSERT target_table (val1, val2, id)  
SELECT stg.val1, stg.val2, stg.id
FROM staging_target_table as stg
WHERE NOT EXISTS (SELECT 1 FROM target_table as t WHERE t.val1 = stg.val1 and t.val2 = stg.val2);