C# SSIS读取System.Object变量并在脚本组件中写入它…如何?

C# SSIS读取System.Object变量并在脚本组件中写入它…如何?,c#,sql-server,ssis,etl,script-component,C#,Sql Server,Ssis,Etl,Script Component,我有一个SSIS包,它以一个脚本任务开始,该任务初始化一个空数据表并将其分配给一个用户变量。我正在添加一些示例行,因为我仍在进行开发。该变量在SSIS中称为:FlatFileBadRowDataTracker public void Main() { // TODO: Add your code here string SSISRunStartTimeStamp = DateTime.Now.ToString("yyyyMMddHHmmss"); Dts.Variable

我有一个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
然后,当我在
Input0\u ProcessInputRow(Input0Buffer Row)
方法中发现与数据相关的错误时,我尝试将数据添加到
dt
中。之后,在
PostExecute()
中,我尝试将
dt
赋值回用户变量

public override void PostExecute()
{
    base.PostExecute();
    Variables.FlatFileBadRowDataTracker = dt;
}
但是,当我运行包时,我得到了这个错误(如下所示),它告诉我不能在PreExecute()方法中使用变量。似乎我只能在PostExecute()方法中使用它。我需要datatable的现有数据+模式,否则我将不得不重新创建模式,并且我将丢失数据(因为现在它只是代码中所示的测试数据)


是否有任何方法可以在脚本组件中获取DataTable的schema+数据?脚本组件也不允许我在
ReadOnlyVariables
ReadWriteVariables
中添加变量。似乎我只能将其添加到其中一个变量。

尝试使用变量分配器,而不是选择变量作为读写变量:

预执行阶段:

IDTSVariables100 vars = null;
VariableDispenser.LockForRead("User::FlatFileBadRowDataTracker");
VariableDispenser.GetVariables(out vars);
dt = (DataTable)vars["User::FlatFileBadRowDataTracker"].Value;
vars.Unlock();
IDTSVariables100 vars = null;
VariableDispenser.LockForWrite("User::FlatFileBadRowDataTracker");
VariableDispenser.GetVariables(out vars);
vars["User::FlatFileBadRowDataTracker"].Value = dt;
vars.Unlock();
执行后阶段:

IDTSVariables100 vars = null;
VariableDispenser.LockForRead("User::FlatFileBadRowDataTracker");
VariableDispenser.GetVariables(out vars);
dt = (DataTable)vars["User::FlatFileBadRowDataTracker"].Value;
vars.Unlock();
IDTSVariables100 vars = null;
VariableDispenser.LockForWrite("User::FlatFileBadRowDataTracker");
VariableDispenser.GetVariables(out vars);
vars["User::FlatFileBadRowDataTracker"].Value = dt;
vars.Unlock();

有关更多信息,请参阅:


    • 关于您收到此类错误消息的原因。读写变量仅在
      PostExecute
      方法中可用;微软这样做是为了减少拥堵的机会。因此,您的错误消息将被抛出到
      PreExecute
      方法。

      Hadi的建议应该在运行脚本组件
      PostExecute
      方法之前访问RW变量。

      谢谢@Hadi。如果我在同一数据流任务中的另一个脚本组件中使用相同的方法,这会导致任何锁定冲突吗?解锁()后是否需要锁定()?我不认为可以在同一数据流任务中多次使用变量,因为该值是在数据流执行结束时提交的(该值在数据流中不会受到影响)。关于变量锁,我认为它可能会导致冲突,但最好尝试一下@gtrivedi