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

SSIS read a System.Object variable and write to it in Script Component...How?

我有一个 SSIS 包,它以一个脚本任务开始,该脚本任务初始化一个空的 DataTable 并将其分配给一个用户变量。我正在添加一些示例行,因为我仍在进行开发。该变量在 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

然后我有一个数据流任务,它读取一个文本文件(通过平面文件源组件的 csv)并有一个脚本组件(作为转换)来确定行是好是坏。好的行被发送到 'GoodRow' 输出,坏行被发送到脚本组件的 'BadRows' 输出。通常情况下,一个文件的大部分行都是正确的,但少数会有数据错误(例如:电子邮件列中有一些不像电子邮件地址的内容),在这种情况下,组件必须将其发送到 BadRows 输出。我的目标是将与错误相关的数据(例如包含数据错误的列名和一些描述)捕获到我之前在脚本任务中创建的同一个数据表中。

我已将此变量添加到脚本组件编辑器属性屏幕下的 ReadWriteVariables 中。我在 PreExecute() 中使用它来获取 DataTable 的模式并将其分配给 dt 这是我在 class.[= 开头声明的局部变量24=]

public override void PreExecute()
{
    base.PreExecute();
    dt = (DataTable)Variables.FlatFileBadRowDataTracker;

} 

然后我尝试将数据添加到 dt 中,当我在 Input0_ProcessInputRow(Input0Buffer Row) method.After 中发现与数据相关的错误时,在 PostExecute() 中我尝试分配 dt返回用户变量。

public override void PostExecute()
{
    base.PostExecute();
    Variables.FlatFileBadRowDataTracker = dt;
}

但是,当我 运行 包时,我收到此错误(如下所示),它告诉我无法在 PreExecute() 方法中使用变量。看来我只能在 PostExecute() 方法中使用它。我需要数据表的现有数据+模式,否则我将不得不重新创建模式并且我将丢失数据(目前它只是代码中所示的测试数据)。

有什么方法可以在我的脚本组件中获取数据表的模式+数据吗?脚本组件也不允许我在 ReadOnlyVariablesReadWriteVariables 中添加变量。看来我只能添加到其中一个。

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

预执行阶段:

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

Post-执行阶段:

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

有关更多信息,请参阅:

  • Unable to fetch "ReadWrite" Variable Value in Script Component of SSIS

关于您收到此类错误消息的原因。读写变量仅在 PostExecute 方法中可用;微软这样做是为了减少拥塞的可能性。因此,您的错误消息是在 PreExecute 方法中抛出的。
Hadi 的建议应该是在 运行 脚本组件 PostExecute 方法之前访问 RW 变量。