SSIS C# 脚本组件:写入包变量仍为空

SSIS C# Script Component: Writing to Package Variable remains empty

我正在从一个 Excel 文件中读取 2 个日期,并试图将这些日期传递给包变量以便在我的包中的其他地方使用。 下面的代码显示了我在哪里执行 Input0_ProcessInputRow 来读取 2 个日期值,然后将它们存储在脚本中的局部变量中。 (vPeriodStart 和 vPeriodEnd)

然后在 PostExecute 中我尝试将我的 PackageVariables 设置为局部变量 - 这没有成功。 调试 MessageBoxes 显示从我的输入中成功读取行,但随后在 PostExecute 中 MessageBoxes 显示值有效 NULL/empty (01/01/0001)

作为 C# 新手,我很确定我还没有理解正确的 functions/placements 用法。感谢这方面的任何指导。

#region Namespaces
using System;
using System.Data;
using System.Windows.Forms;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
#endregion


[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
DateTime vPeriodStart;
DateTime vPeriodEnd;

public override void PreExecute()
{
    base.PreExecute();
}

public override void PostExecute()
{
    base.PostExecute();
    
    MessageBox.Show("3 vPeriodStart: " + vPeriodStart.ToString());
    MessageBox.Show("4 vPeriodEnd: " + vPeriodEnd.ToString());

    Variables.HarveyNormanAUPeriodStart = vPeriodStart;
    Variables.HarveyNormanAUPeriodEnd = vPeriodEnd;
}

public override void Input0_ProcessInputRow(Input0Buffer Row)
{
    DateTime vPeriodStart = DateTime.Parse(Row.PeriodStart);
    DateTime vPeriodEnd = DateTime.Parse(Row.PeriodEnd);

    MessageBox.Show("1 vPeriodStart: " + vPeriodStart.ToString());
    MessageBox.Show("2 vPeriodEnd: " + vPeriodEnd.ToString());

}

}

就设置变量而言,Brad 上面的注释是正确的。

除此之外,如果您在 C# 中遇到 null,则在尝试设置不可为 null 的变量时会出现 null 对象引用错误。 Input0_ProcessInputRow 为每一行调用,因此在当前代码中,每一行都会调用日期变量。我的猜测是最后一行有一些奇怪的日期,比如 1/1/0000,所以变量被设置了几次。我 运行 你的代码只有一行数据,它像你期望的那样工作。

你能试试这样吗,添加一个变量,这样你只设置一次日期:

#region Namespaces
using System;
using System.Data;
using System.Windows.Forms;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
#endregion


[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
DateTime vPeriodStart;
DateTime vPeriodEnd;
bool isFirstRow = true;

public override void PreExecute()
{
    base.PreExecute();
}

public override void PostExecute()
{
    base.PostExecute();
    
    MessageBox.Show("3 vPeriodStart: " + vPeriodStart.ToString());
    MessageBox.Show("4 vPeriodEnd: " + vPeriodEnd.ToString());

    Variables.HarveyNormanAUPeriodStart = vPeriodStart;
    Variables.HarveyNormanAUPeriodEnd = vPeriodEnd;
}

public override void Input0_ProcessInputRow(Input0Buffer Row)
{
    if(isFirstRow)
    {
    DateTime vPeriodStart = DateTime.Parse(Row.PeriodStart);
    DateTime vPeriodEnd = DateTime.Parse(Row.PeriodEnd);

    MessageBox.Show("1 vPeriodStart: " + vPeriodStart.ToString());
    MessageBox.Show("2 vPeriodEnd: " + vPeriodEnd.ToString());
    isFirstRow = false;
    }

}

}

简答: 我在 Input0_ProcessInputRow 中重新声明了我的变量,尽管我的输入中只有 1 条记录,但似乎 运行 至少两次,然后覆盖了我的变量。

我是如何得出这个的详细信息: 在继续我的故障排除过程中,我注意到调试实际上在触发 PostExecute 部分中的 MessageBoxes 3 和 4 之前完成(绿色勾号)。

即使我只从我的输入返回 1 行

这让我想到我的变量中 NULL/Empty 值的原因是因为脚本在到达 PostExecute 部分之前似乎已经完成并清除了局部变量(vPeriodStart、vPeriodEnd)。

这让我想知道变量 vPeriodStart 和 vPeriodEnd 是如何被清除的——这几乎就像它们被“重新定义”了一样……看看我的代码,我猜我的第二个 DateTime 声明对于 2 个变量,实际上是覆盖正确写入它们的初始值。 (这种想法受到@Mark 的启发 - 尽管我确实只有 1 条记录作为输入并且 isFirstRow 验证没有效果,但我天真地假设 Input0_ProcessInputRow 部分有一个 EndOfFile 引用并且它 运行 通过第二次然后在退出到 PostExecute 部分之前重新声明我的变量)

通过简单地删除 Input0_ProcessInputRow 部分中的第二个声明,现在一切正常,变量值保留足够长的时间以到达 PostExecute 部分,然后我的包变量将在此处成功更新。