我有以下行的数据:
Name1 Name2 Name3 Col
aaa bbb ccc ...
abc ddd ddd 1
abc ddd ddd 2
abc ddd ddd 3
fff fff fff ...
ggg ggg hhh 4
ggg ggg hhh 5
Run Code Online (Sandbox Code Playgroud)
(Name1,Name2并且Name3是主键)
如何使用相同的3个主键从数据集中删除第一行?(留下仅设定的最后一行)
即上述结果将是:
Name1 Name2 Name3 Col
aaa bbb ccc ...
abc ddd ddd 3
fff fff fff ...
ggg ggg hhh 5
Run Code Online (Sandbox Code Playgroud)
假设您的源数据顺序正确,并且您想要每组中的最后一条记录,则没有任何开箱即用的转换可以处理这种情况。然而,脚本转换可以相当容易地处理它。
这是一个示例数据流:

为了简单起见,我使用FF_SRC_AllRows和FF_DST_SelectedRows作为平面文件源和目标(分别),使用您提供的示例数据;您的具体需求会有所不同。脚本转换SCR_SelectLastRow配置为转换(输入和输出):

选择所有输入列(使用类型ReadOnly):

创建一个输出(我将其命名为我的OutgoingRows,但您可以将其命名为任何您想要的名称),并将SynchronousInputID属性设置为None. 这将使您的脚本过滤掉您不需要的行。

添加与输入列对应的输出列:

并使用以下代码:
/* Microsoft SQL Server Integration Services Script Component
* Write scripts using Microsoft Visual C# 2008.
* ScriptMain is the entry point class of the script.*/
using System;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
class IncomingRowData
{
public string Name1;
public string Name2;
public string Name3;
public string Col;
public IncomingRowData(IncomingRowsBuffer Row)
{
Name1 = Row.Name1;
Name2 = Row.Name2;
Name3 = Row.Name3;
Col = Row.Col;
}
public bool KeysDiffer(IncomingRowData other)
{
return (Name1 != other.Name1
|| Name2 != other.Name2
|| Name3 != other.Name3);
}
public void WriteToOutputBuffer(OutgoingRowsBuffer Row)
{
Row.AddRow();
Row.Name1 = Name1;
Row.Name2 = Name2;
Row.Name3 = Name3;
Row.Col = Col;
}
}
private IncomingRowData _previousRow;
public override void IncomingRows_ProcessInputRow(IncomingRowsBuffer Row)
{
if (_previousRow == null)
{
_previousRow = new IncomingRowData(Row);
}
IncomingRowData currentRow = new IncomingRowData(Row);
if (currentRow.KeysDiffer(_previousRow))
{
_previousRow.WriteToOutputBuffer(this.OutgoingRowsBuffer);
}
_previousRow = currentRow;
}
public override void FinishOutputs()
{
if (_previousRow != null)
{
_previousRow.WriteToOutputBuffer(this.OutgoingRowsBuffer);
}
base.FinishOutputs();
}
}
Run Code Online (Sandbox Code Playgroud)
这项技术的一个好处是,它允许您一次性处理数据,并且不需要使用临时表,也不需要将整个源数据集保留在内存中。根据您的数据集有多大,其中任何一个都可能会导致严重的性能问题。