使用SSIS包,如何在插入之前验证源记录是否重复?

时间:2018-07-04 20:12:59

标签: sql sql-server ssis

SQL Server 2012:使用SSIS包,如何在插入之前验证源记录是否重复?

我们的源文件是.csv。我们正面临登台表中加载的重复记录。

目前,我们正在遵循手动加载数据的过程。

如何在加载和仅加载有效记录之前针对目标表验证源文件数据?加载重复记录的可能性不仅是因为源文件中包含重复记录,而且还可能将同一文件重新加载到登台表中。

我们不截断登台表。我们将保持原样。

第二个问题:如何选择源文件的名称并在加载时传递它?可能有一个派生列为“ FileName”,它将与原始数据一起加载到登台表中。

3 个答案:

答案 0 :(得分:2)

在这种情况下,我使用的典型负载模式是:

  1. 准备与源文件匹配的登台表
  2. 在SSIS中,使用TRUNCATE StagingTable;(将其清除)运行SQL任务
  3. 然后,运行一个数据流任务,将整个数据文件加载到登台表中
  4. 最后,将登台表合并到最终表中。

我更喜欢在SQL任务的最后一步:

INSERT INTO FinalTable 
(PrimaryKey,Column1,Column2,Column3)
SELECT 
PrimaryKey,Column1,Column2,Column3 
FROM StagingTable SRC
WHERE NOT EXISTS (
    SELECT * FROM FinalTable TGT WHERE TGT.PrimaryKey=SRC.PrimaryKey
);

如果您喜欢图形用户界面,并且不介意额外的网络流量和较慢的处理时间,则可以使用查找执行相同类型的合并操作。您甚至可以使用SCD组件,但我强烈不建议使用它。

无论是在T-SQL还是UI中进行操作,都需要一个可用于唯一标识记录的密钥(在我的示例中称为PrimaryKey)。如果您没有此密钥,则无法“重复数据删除”

请注意,在此示例中,您有一个“真实”登台表,其唯一目的是将数据文件放入数据库中。然后,您将获得一个包含最终一致结果的最终表

还请注意,此模式仅添加新行-如果数据文件中的现有行发生更改,则不会更新现有行。

答案 1 :(得分:1)

两年前,我在导入TSV文件时遇到了同样的问题。 我尝试了许多其他解决方案,但我能设计的最好的方法是C#代码脚本,以实现最佳验证。

我作为解决方案所做的

  • 使用DataTable在内存中创建一个C#Primary Key constraints对象,

    like:-

  

DataColumn[] keyColumn = new DataColumn[30];

     

keyColumn[intJ] = dtFilterdPK.Columns["Column name"];

  • 然后尝试将CS​​V中的一行一行添加到此数据表中。
  • 每当您的数据基于主键重复时就会出现错误
  • (TRY)..CATCH块中处理此错误代码,并根据您的日志记录要求进行此重复错误。
  • 避免将这些错误记录导入DataTable对象中。
  • Atlast以BulkImport格式将CSV文件导入到表中 Like
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(myConnection))
{
bulkCopy.DestinationTableName = "Your DB Table Name";   //Assign table name
bulkCopy.WriteToServer(dtToBeImport);   //Write into Actual table.
}

希望这会对您有所帮助。

答案 2 :(得分:1)

  1. 鉴于您的确切情况(再次加载同一文件),我将首先检查数据是否甚至已加载到登台表。如果这样做,则不必担心在记录级别检查重复项。

  2. 如何设置与文件的连接?我已经处理了大多数数据负载,我设计了for-each-loop-container,其中文件名/路径将填充在用户变量中。如您所说,您可以仅使用派生列转换来添加新列,该新列从变量获取值。如果用户变量中没有文件名,则可以在控制流中使用表达式任务来填充它。

为了满足您的确切要求,我将使用以上步骤在表中填充文件名。您甚至可以规范化为其他表,而不是为每个数据记录存储长文件名。在数据库中拥有所有文件名之后,只需在开始处使用“ Execute SQL”即可查看该文件名是否已在数据库中。