我有一个包含BeginDate字段的合约表,但在SQL Server 2000数据库上没有结束日期(畏缩)。我正在使用2008环境中设计的SSIS包将数据从此表移动到数据仓库的暂存数据库中。我需要计算结束日期。
结束日期是客户的下一个合约开始日期减去一天。
除了SQL Server 2000以外,这对于CTE来说很容易。我使用了一个使用行号合并到集合的策略,即使这在这里也不起作用。
我的策略是通过数据源组件提取日期。像这样:
SELECT CustomerId, ContractStartDate FROM Contracts
然后,我将使用脚本组件并覆盖ProcessInput方法以遍历结果集并将结束日期添加为输出值。
这似乎是一种可怜的方法,但鉴于我的约束,可能是最好的方法。谁能想到其他任何选择?
答案 0 :(得分:1)
经过一些进一步的研究后,我发现不可能随意遍历输入缓冲区。
解决方案对这个问题有点反直觉。您可以做的最好的事情是根据之前的值修改当前行,而不是识别和修改下一行。这意味着需要从客户ID中的最大日期到最小日期评估数据。
为了保持连续性,我会将我的例子保留在原始问题的背景下。
假设我们有脚本组件的输入数据。添加排序组件以按CustomerID
排序记录集,然后按ContractStartDate
降序排序。
然后在脚本组件中添加CustomerID
和ContractStartDate
作为输入,并添加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个月。