0

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

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

除了 SQL Server 2000 之外,这对 CTE 来说很容易做到。我使用了一种使用行号合并到集合的策略,即使在这里也行不通。

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

SELECT CustomerId, ContractStartDate FROM Contracts

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

这似乎是一种可悲的方法,但考虑到我的限制,可能是最好的方法。谁能想到其他选择?

4

1 回答 1

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 个月的。

于 2013-05-20T12:25:38.653 回答