当 SSIS 中的 C# 转换需要同步时,在输出缓冲区中使用 AddRow()?
Using AddRow() in Output Buffer when C# transform in SSIS needs synchronous?
首先,我对 SSIS 和 C# 都很陌生,对于任何菜鸟错误深表歉意。我试图通过从具有可变长度 header 和页脚的输入文件中用特定分隔符拆分一列来混淆我的方式。
例如,Input0Buffer 有一列。实际数据前面总是以短语 "STARTDATA" 开头的行,并用括号括起以 "ENDDATA".
开头的行
一个输入列包含由 | 分隔的 5 位数据.其中两列我不关心。
输入文件基本上是这样的:
垃圾堆
header东西
更多垃圾
开始数据
ID1|垃圾|东西|苹果|奶酪
ID2|獾|垃圾|梨|酸奶
到目前为止,我已经尝试在 C# 转换器中加入一些 row-by-row 逻辑,我认为我对此很满意 - 但我不知道如何让它输出我的拆分数据。代码如下。
bool passedSOD;
bool passedEOD;
public void ProcessRow(Input0Buffer data)
{
string Col1, Col2, Col3;
if (data.Column0.StartsWith("ENDDATA"))
{
passedEOD = true;
}
if (passedSOD && !passedEOD)
{
var SplitData = data.Column0.Split('|');
Col1 = SplitData[0];
Col2 = SplitData[3];
Col3 = SplitData[4];
//error about Output0Buffer not existing in context
Output0Buffer.Addrow();
Output0Buffer.prodid = Col1;
Output0Buffer.fruit = Col2;
Output0Buffer.dairy = Col3;
}
if (data.Column0.StartsWith("STARTDATA"))
{
passedSOD = true;
}
}
如果我将输出更改为异步,它会停止有关当前上下文中不存在的 Output0Buffer 的错误,并且它会运行,但会输出 0 行 - 大概是因为我需要同步处理每一行我已经设置好了?
非常感谢任何帮助。
您可以通过检查该行是否包含“|”来缩短您的代码
if(Row.Column0.Contains("|")
{
string[] cols = Row.Column0.Split('|');
Output0Buffer.AddRow();
Output0Buffer.prodid = cols[0];
Output0Buffer.fruit = cols[3];
Output0Buffer.dairy = cols[4];
}
就像比尔说的。确保这是一个转换组件而不是目标。您的选项是源、转换和目标。
您也可能希望将此作为不同的输出。否则,您将需要有条件地拆分 "extra" 行。
感谢两位的回答 - 这是一个转换,感谢您提供更短的方式,但是页眉和页脚的格式不正确并且可能还包含垃圾字符,所以我不敢冒险寻找 |在行中。但我一定会把它储存起来,以便下次处理格式更好的文件。
我在这个论坛之外得到了回复,所以我想我应该回答我自己的问题,以防其他人有类似的问题。
注意:
这是一个转换
在脚本转换编辑器的输入和输出部分中将输出设置为 SynchronousInputID = None
我的输入名为 Input,包含一列名为 RawData
我的输出称为 GenOutput,具有三列
虽然输入文件只有5个字段,但尾部有一个|在每一行的末尾,所以这算作 6
将同步设置为 None 意味着现在可以在上下文中识别 Output0Buffer。
适用于我的代码是:
bool passedSOD;
bool passedEOD;
public override void_InputProcessInputRow(InputBuffer Row)
{
if (Row.RawData.Contains("ENDDATA"))
{
passedEOD = true;
GenOutputBuffer.SetEndOfRowset();
}
//IF WE HAVE NOT PASSED THE END OF DATA, BUT HAVE PASSED THE START OF DATA, SPLIT THE ROW
if (passedSOD && !passedEOD)
{
var SplitData = Row.RawData.Split('|');
//ONLY PROCESS IF THE ROW CONTAINS THE RIGHT NUMBER OF ELEMENTS I.E. EXPECTED NUMBER OF DELIMITERS
if (SplitData.Length == 6)
{
GenOutputBuffer.AddRow();
GenOutputBuffer.prodid = SplitData[0];
GenOutputBuffer.fruit = SplitData[3];
GenOutputBuffer.dairy = SplitData[4];
}
//SILENTLY DROPPING ROWS THAT DO NOT HAVE RIGHT NUMBER OF ELEMENTS FOR NOW - COULD IMPROVE THIS LATER
}
if (Row.RawData.Contains("STARTDATA"))
{
passedSOD = true;
}
}
现在我只需要弄清楚如何将其他字段之一从字符串转换为十进制,但十进制为 null 并允许它在有人在该字段中转储 "N.A" 时输出 null : D
首先,我对 SSIS 和 C# 都很陌生,对于任何菜鸟错误深表歉意。我试图通过从具有可变长度 header 和页脚的输入文件中用特定分隔符拆分一列来混淆我的方式。
例如,Input0Buffer 有一列。实际数据前面总是以短语 "STARTDATA" 开头的行,并用括号括起以 "ENDDATA".
开头的行一个输入列包含由 | 分隔的 5 位数据.其中两列我不关心。
输入文件基本上是这样的:
垃圾堆
header东西
更多垃圾
开始数据
ID1|垃圾|东西|苹果|奶酪
ID2|獾|垃圾|梨|酸奶
到目前为止,我已经尝试在 C# 转换器中加入一些 row-by-row 逻辑,我认为我对此很满意 - 但我不知道如何让它输出我的拆分数据。代码如下。
bool passedSOD;
bool passedEOD;
public void ProcessRow(Input0Buffer data)
{
string Col1, Col2, Col3;
if (data.Column0.StartsWith("ENDDATA"))
{
passedEOD = true;
}
if (passedSOD && !passedEOD)
{
var SplitData = data.Column0.Split('|');
Col1 = SplitData[0];
Col2 = SplitData[3];
Col3 = SplitData[4];
//error about Output0Buffer not existing in context
Output0Buffer.Addrow();
Output0Buffer.prodid = Col1;
Output0Buffer.fruit = Col2;
Output0Buffer.dairy = Col3;
}
if (data.Column0.StartsWith("STARTDATA"))
{
passedSOD = true;
}
}
如果我将输出更改为异步,它会停止有关当前上下文中不存在的 Output0Buffer 的错误,并且它会运行,但会输出 0 行 - 大概是因为我需要同步处理每一行我已经设置好了?
非常感谢任何帮助。
您可以通过检查该行是否包含“|”来缩短您的代码
if(Row.Column0.Contains("|")
{
string[] cols = Row.Column0.Split('|');
Output0Buffer.AddRow();
Output0Buffer.prodid = cols[0];
Output0Buffer.fruit = cols[3];
Output0Buffer.dairy = cols[4];
}
就像比尔说的。确保这是一个转换组件而不是目标。您的选项是源、转换和目标。
您也可能希望将此作为不同的输出。否则,您将需要有条件地拆分 "extra" 行。
感谢两位的回答 - 这是一个转换,感谢您提供更短的方式,但是页眉和页脚的格式不正确并且可能还包含垃圾字符,所以我不敢冒险寻找 |在行中。但我一定会把它储存起来,以便下次处理格式更好的文件。
我在这个论坛之外得到了回复,所以我想我应该回答我自己的问题,以防其他人有类似的问题。
注意:
这是一个转换
在脚本转换编辑器的输入和输出部分中将输出设置为 SynchronousInputID = None
我的输入名为 Input,包含一列名为 RawData
我的输出称为 GenOutput,具有三列
虽然输入文件只有5个字段,但尾部有一个|在每一行的末尾,所以这算作 6
将同步设置为 None 意味着现在可以在上下文中识别 Output0Buffer。
适用于我的代码是:
bool passedSOD;
bool passedEOD;
public override void_InputProcessInputRow(InputBuffer Row)
{
if (Row.RawData.Contains("ENDDATA"))
{
passedEOD = true;
GenOutputBuffer.SetEndOfRowset();
}
//IF WE HAVE NOT PASSED THE END OF DATA, BUT HAVE PASSED THE START OF DATA, SPLIT THE ROW
if (passedSOD && !passedEOD)
{
var SplitData = Row.RawData.Split('|');
//ONLY PROCESS IF THE ROW CONTAINS THE RIGHT NUMBER OF ELEMENTS I.E. EXPECTED NUMBER OF DELIMITERS
if (SplitData.Length == 6)
{
GenOutputBuffer.AddRow();
GenOutputBuffer.prodid = SplitData[0];
GenOutputBuffer.fruit = SplitData[3];
GenOutputBuffer.dairy = SplitData[4];
}
//SILENTLY DROPPING ROWS THAT DO NOT HAVE RIGHT NUMBER OF ELEMENTS FOR NOW - COULD IMPROVE THIS LATER
}
if (Row.RawData.Contains("STARTDATA"))
{
passedSOD = true;
}
}
现在我只需要弄清楚如何将其他字段之一从字符串转换为十进制,但十进制为 null 并允许它在有人在该字段中转储 "N.A" 时输出 null : D