基于SSIS中下一行的字段计算值

时间:2013-05-17 17:01:57

标签: sql-server-2000 ssis-2008

我有一个包含BeginDate字段的合约表,但在SQL Server 2000数据库上没有结束日期(畏缩)。我正在使用2008环境中设计的SSIS包将数据从此表移动到数据仓库的暂存数据库中。我需要计算结束日期。

结束日期是客户的下一个合约开始日期减去一天。

除了SQL Server 2000以外,这对于CTE来说很容易。我使用了一个使用行号合并到集合的策略,即使这在这里也不起作用。

我的策略是通过数据源组件提取日期。像这样:

SELECT CustomerId, ContractStartDate FROM Contracts

然后,我将使用脚本组件并覆盖ProcessInput方法以遍历结果集并将结束日期添加为输出值。

这似乎是一种可怜的方法,但鉴于我的约束,可能是最好的方法。谁能想到其他任何选择?

1 个答案:

答案 0 :(得分:1)

经过一些进一步的研究后,我发现不可能随意遍历输入缓冲区。

解决方案对这个问题有点反直觉。您可以做的最好的事情是根据之前的值修改当前行,而不是识别和修改下一行。这意味着需要从客户ID中的最大日期到最小日期评估数据。

为了保持连续性,我会将我的例子保留在原始问题的背景下。

假设我们有脚本组件的输入数据。添加排序组件以按CustomerID排序记录集,然后按ContractStartDate降序排序。

然后在脚本组件中添加CustomerIDContractStartDate作为输入,并添加ContractEndDate作为输出值。

覆盖Input0_ProcessInputRow。默认情况下会生成执行此操作的代码。

添加一些属性以跟踪上一个开始日期和上一个客户,并根据前一行设置当前行的结束日期值。

您的脚本将如下所示:

public DateTime? PreviousRowStartDate { get; set; }
public string PreviousRowCustomerID { get; set; }
public int KnownContractPeriod { get; set; }
int defaultContractPeriod = 12;

public override void Input0_ProcessInputRow(Input0Buffer Row)
{
    if (PreviousRowCustomerID == Row.CustomerID)
    {
        Row.ContractEndDate= PreviousRowStartDate.Value.AddDays(-1);
    }
    else
    {
        Row.ContractEndDate= Row.ContractStartDate.AddMonths(defaultContractPeriod).AddDays(-1);
    }
    PreviousRowCustomerID = Row.CustomerID;
    PreviousRowStartDate = Row.ContractStartDate;
}

在处理第一份合同(客户最新)时会发生故障。出于这个原因,我已经包含了默认合同期。

这个问题实际上可能会让我感到困惑,但现在很难说,因为这里的大多数合同都是12个月。