[英]SSIS read a System.Object variable and write to it in Script Component...How?
I have a SSIS package which starts with a Script Task which initializes an empty DataTable and assigns it to a user variable.我有一个 SSIS 包,它从一个脚本任务开始,它初始化一个空的 DataTable 并将它分配给一个用户变量。 I'm adding some sample rows as I'm still doing development.我正在添加一些示例行,因为我仍在进行开发。 The variable is called: FlatFileBadRowDataTracker
in SSIS.该变量在 SSIS 中称为: FlatFileBadRowDataTracker
。
public void Main()
{
// TODO: Add your code here
string SSISRunStartTimeStamp = DateTime.Now.ToString("yyyyMMddHHmmss");
Dts.Variables["User::SSISRunStartTimeStamp"].Value = SSISRunStartTimeStamp;
Dts.Variables["User::FlatFileBadRowDataTracker"].Value = BuildSampleDataTable();
Dts.TaskResult = (int)ScriptResults.Success;
}
private DataTable BuildSampleDataTable()
{
DataTable dt = new DataTable();
// ErrorColumn
DataColumn errorColumn = new DataColumn("ErrorColumn");
errorColumn.DataType = System.Type.GetType("System.String");
errorColumn.DefaultValue = string.Empty;
dt.Columns.Add(errorColumn);
// ErrorDescription
DataColumn errorDescription = new DataColumn("ErrorDescription");
errorColumn.DataType = System.Type.GetType("System.String");
errorColumn.DefaultValue = string.Empty;
dt.Columns.Add(errorDescription);
// FileName
DataColumn fileName = new DataColumn("FileName");
errorColumn.DataType = System.Type.GetType("System.String");
errorColumn.DefaultValue = string.Empty;
dt.Columns.Add(fileName);
// RawData
DataColumn rawData = new DataColumn("RawData");
errorColumn.DataType = System.Type.GetType("System.String");
errorColumn.DefaultValue = string.Empty;
dt.Columns.Add(rawData);
// ErrorDescription
DataColumn dataFlowComponent = new DataColumn("DataFlowComponent");
errorColumn.DataType = System.Type.GetType("System.String");
errorColumn.DefaultValue = string.Empty;
dt.Columns.Add(dataFlowComponent);
// Populate with some sample data.
DataRow row;
for (int i = 1; i < 5; i++)
{
row = dt.NewRow();
row["ErrorColumn"] = "ErrorColumn" + i;
row["ErrorDescription"] = "ErrorDescription" + i;
row["FileName"] = "FileName" + i;
row["RawData"] = "RawData" + i;
row["DataFlowComponent"] = "SSIS_DataFlowTask_" + i;
dt.Rows.Add(row);
}
return dt;
}
#region ScriptResults declaration
/// <summary>
/// This enum provides a convenient shorthand within the scope of this class for setting the
/// result of the script.
///
/// This code was generated automatically.
/// </summary>
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
Then I have a Data Flow Task which reads a text file (csv through a Flat File Source component) and has a Script Component (as transformation) which determines whether the rows are good or bad.然后我有一个数据流任务,它读取一个文本文件(通过平面文件源组件的 csv)并有一个脚本组件(作为转换)来确定行是好还是坏。 Good rows are send to a 'GoodRow' output and bad rows are sent to 'BadRows' output from the Script Component.好的行被发送到“GoodRow”输出,坏的行被发送到“脚本组件”的“BadRows”输出。 Usually a file will have mostly good rows but a few will have data errors (example: the email column has something which doesn't resemble an email address), in which case the component has to send this to BadRows output.通常一个文件的大部分行都是好的,但也有一些会有数据错误(例如:电子邮件列有一些与电子邮件地址不同的东西),在这种情况下,组件必须将其发送到 BadRows 输出。 My goal is to capture the error related data (such as the column name which has the data error and some description along with that) into the same DataTable I created in the Script Task earlier.我的目标是将与错误相关的数据(例如包含数据错误和一些描述的列名)捕获到我之前在脚本任务中创建的同一个 DataTable 中。
I have added this variable in the ReadWriteVariables under the Properties of the Script Component Editor screen.我在脚本组件编辑器屏幕的属性下的ReadWriteVariables 中添加了这个变量。 I'm using it in the PreExecute()
to obtain the schema of the DataTable and assign it to dt
which is a local variable I'm declared at the beginning of the class.我在PreExecute()
使用它来获取 DataTable 的模式并将其分配给dt
,这是我在课程开始时声明的局部变量。
public override void PreExecute()
{
base.PreExecute();
dt = (DataTable)Variables.FlatFileBadRowDataTracker;
}
Then I try to add data into dt
as and when I find data related errors in Input0_ProcessInputRow(Input0Buffer Row)
method.After that in the PostExecute()
I try to assign dt
back to the user variable.然后,当我在Input0_ProcessInputRow(Input0Buffer Row)
发现与数据相关的错误时,我尝试将数据添加到dt
中。之后在PostExecute()
我尝试将dt
分配回用户变量。
public override void PostExecute()
{
base.PostExecute();
Variables.FlatFileBadRowDataTracker = dt;
}
However, when I run the package I get this error (shown below) which tells me that I cannot use the variable in the PreExecute() method.但是,当我运行该包时,出现此错误(如下所示),它告诉我无法在 PreExecute() 方法中使用该变量。 It seems I can only use it in PostExecute() method.看来我只能在 PostExecute() 方法中使用它。 I need the existing data+schema of the datatable, otherwise I will have to recreate the schema and I'll lose the data (For now its just the test data as shown in code).我需要数据表的现有数据+模式,否则我将不得不重新创建模式并且我将丢失数据(现在它只是代码中显示的测试数据)。
Is there any way I can get the schema+data of the DataTable in my Script Component?有什么方法可以在我的脚本组件中获取 DataTable 的架构 + 数据? The Script Component also doesn't let me add the variable in both ReadOnlyVariables
and ReadWriteVariables
.脚本组件也不允许我在ReadOnlyVariables
和ReadWriteVariables
添加变量。 It seems I can add it to only one of them.看来我只能将它添加到其中之一。
Try using Variable dispenser instead of selecting variable as ReadWrite Variable:尝试使用变量分配器而不是选择变量作为读写变量:
Pre-Execute phase:预执行阶段:
IDTSVariables100 vars = null;
VariableDispenser.LockForRead("User::FlatFileBadRowDataTracker");
VariableDispenser.GetVariables(out vars);
dt = (DataTable)vars["User::FlatFileBadRowDataTracker"].Value;
vars.Unlock();
Post-Execute phase:执行后阶段:
IDTSVariables100 vars = null;
VariableDispenser.LockForWrite("User::FlatFileBadRowDataTracker");
VariableDispenser.GetVariables(out vars);
vars["User::FlatFileBadRowDataTracker"].Value = dt;
vars.Unlock();
For Additional information, refer to:有关其他信息,请参阅:
On the reason why you receive such error messages.关于您收到此类错误消息的原因。 Read-Write Variables are available only at PostExecute
method;读写变量仅在PostExecute
方法中可用; Microsoft did this to reduce chances of congestion.微软这样做是为了减少拥塞的机会。 So, your error message is thrown at PreExecute
method.因此,您的错误消息是在PreExecute
方法中抛出的。
Hadi's recommendations should do the trick of accessing your RW variable before running Script Component PostExecute
method. Hadi 的建议应该在运行 Script Component PostExecute
方法之前执行访问 RW 变量的技巧。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.