你可以使用:
- 使用条件拆分转换的聚合转换
将聚合转换带到数据流窗格并将您的 Excel 文件源连接到聚合转换。您需要将它们分组并计数。
将条件拆分转换拖动到数据流窗格并将聚合转换连接到它。
通过使用条件拆分,您会将重复记录重定向到输出,您可以将它们写入表/文件。
使用 Cast Function (DT_I4) 将 [Count All] 转换为 Int。
条件拆分转换将创建两个输出:
-
DuplicateRecords 重复记录
-
CorrectRecords 获取唯一记录
带上Multicast Transformation 并将Conditional Split Transformation 的DuplicateRecords 输出连接到它。
带上一个 OLE DB 目标并将来自 Conditional Split Transformation 的 CorrectRecords 输出连接到它。
将数据查看器放在它们之间,以便您可以显示记录。您将实时将这些记录写入目标表/文件。
2。查找组件:
在控制流中添加Lookup task,并加入Excel文件任务。
在Lookup Transformation Editor 中,指定连接管理器和缓存类型。
在指定如何处理没有匹配条目的行的下拉列表中,选择以下选项:
Redirect rows to no match output
单击连接并从下拉列表中指定目标表。您在同一个数据库中同时拥有源表和目标表。您也可以在此处创建单独的连接。
单击列,它会显示源表和目标表。
您想比较 Excel 文件和目标表上的 ID 列。从源中拖动 ID 列并将其移动到目标 ID 列。
从 SSIS 工具箱中添加 OLE DB destination。使用OLE DB destination 加入查找任务,它会打开以下输入-输出选择。
选择以下值:
- 输出:查找不匹配输出:您将其附加到
OLE DB destination(SQL Server 数据库中的表)
- 输入:OLE DB 目标输入:例如,将其附加到平面文件目标
3. SSIS 排序结合脚本组件:
将您的源添加到数据流任务。
您需要对要用于重复数据删除的列进行排序。一般来说,如果你的源是一个数据库表,那么你应该在查询中添加一个GROUP BY 子句,否则你应该在你的源之后添加一个SORT Transformation。
在排序后的源代码之后添加一个脚本组件类型转换。
编辑Script Component 并转到Input Columns tab 并选择您要用于重复数据删除的所有列ReadOnly(与您用于排序的字段相同)。
转到输入和输出选项卡并将输出端口的名称从“输出 0”更改为“唯一”。还将 ExclusionGroup 更改为 1。
添加一个新输出并将其命名为 Duplicate 并将 ExlusionGroup 更改为 1。要将此新输出端口连接到输入端口,请更改 SynchronousInputID 属性并选择输入端口。
编辑脚本并复制以下代码。此脚本使用反射来获取所有选定的列,因此如果您更改输入列,则不必更改脚本。但请阅读编码 cmets。
// C# code
// This script automaticly compares the selected columns, but there is one 'bug':
// You have to edit and close this script again if you change input columns.
using System;
using System.Data;
using System.Reflection; // Added
using System.Text; // Added
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
// Create a variable to store the concatenated values for the previous row
string previousRow = "";
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
// Create a variable to store the concatenated values of current row
StringBuilder currentRow = new StringBuilder();
foreach (PropertyInfo p in Row.GetType().GetProperties())
{
// We can't use the _IsNull columns, so ignore them. Also ignore the new output column
if ((p.Name.ToLower().EndsWith("_IsNull") == false) && (p.Name.Equals("Duplicate") == false))
{
try
{
// Concatenate value as string to variable
currentRow.Append(p.GetValue(Row, null).ToString() + "|");
}
catch (ArgumentException)
{
// If the value is NULL (empty) then you can't get the value of it
currentRow.Append("NULL|");
}
catch (Exception ex)
{
// Raise error because something unexpected went wrong
bool pbCancel = false;
this.ComponentMetaData.FireError(0, "MarkDuplicates", p.Name + ": " + ex.Message, string.Empty, 0, out pbCancel);
}
}
}
// Check if the current row and previous row are the same
if (currentRow.ToString().Equals(previousRow))
{
// Redirect to duplicate output
Row.DirectRowToDuplicate();
}
else
{
// Redirect to unique output
Row.DirectRowToUnique();
}
// Fill previous row with current value for next check
previousRow = currentRow.ToString();
}
}
或 VB.Net :
' VB.Net code
' This script automaticly compares the selected columns, but there is one 'bug':
' You have to edit and close this script again if you change input columns.
Imports System
Imports System.Data
Imports System.Math
Imports System.Reflection ' Added
Imports System.Text ' Added
Imports Microsoft.SqlServer.Dts.Pipeline.Wrapper
Imports Microsoft.SqlServer.Dts.Runtime.Wrapper
<Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute> _
<CLSCompliant(False)> _
Public Class ScriptMain
Inherits UserComponent
' Create a variable to store the concatenated values for the previous row
Dim previousRow As String = ""
Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)
' Create a variable to store the concatenated values of current row
Dim currentRow As StringBuilder = New StringBuilder()
Dim p As PropertyInfo
For Each p In Row.GetType().GetProperties()
' We can't use the _IsNull columns, so ignore them. Also ignore the new output column
If ((p.Name.ToLower().EndsWith("_IsNull") = False) And (p.Name.Equals("Duplicate") = False)) Then
Try
' Concatenate value as string to variable
currentRow.Append(p.GetValue(Row, Nothing).ToString() + "|")
Catch ex As ArgumentException
' If the value is NULL (empty) then you can't get the value of it
currentRow.Append("NULL|")
Catch ex As Exception
' Raise error because something unexpected went wrong
Dim pbCancel As Boolean
Me.ComponentMetaData.FireError(0, "MarkDuplicates", p.Name + ": " + ex.Message, String.Empty, 0, pbCancel)
End Try
End If
Next
' Check if the current row and previous row are the same
If (currentRow.ToString().Equals(previousRow)) Then
' Redirect to duplicate output
Row.DirectRowToDuplicate()
Else
' Redirect to unique output
Row.DirectRowToUnique()
End If
' Fill previous row with current value for next check
previousRow = currentRow.ToString()
End Sub
End Class
添加两个目的地并将Data Flow Paths 连接到目的地。连接时,您必须选择输出端口。
不要忘记添加一些数据查看器用于测试目的。