我在SSIS中使用脚本任务,其中我使用三个不同的记录集来向数据流添加行。一切都适用于第一次使用这些记录集,但当其他行需要访问记录集时,其中没有数据。
我要做的是在传入的数据流中获取这些行:
ID | mScale | startDate | End Date ....
1 | w | 7/8/13 | 10/31/13
1 | m | 11/1/13 | 3/31/14
1 | q | 4/1/14 | 7/31/14
2 | w | 7/8/13 | 10/31/13
2 | m | 11/1/13 | 3/31/14
2 | q | 4/1/14 | 7/31/14
并添加行,以便传出数据流如下所示:
ID | pScale | startDate | EndDate
1 | w | 7/8/13 | 7/14/13
1 | w | 7/15/13 | 7/21/13
....
1 | w | 10/28/13 | 10/31/13
1 | m | 11/1/13 | 11/30/13
1 | m | 12/1/13 | 12/31/13
...
1 | m | 3/1/14 | 3/31/14
1 | q | 4/1/14 | 6/30/14
1 | q | 7/1/14 | 7/31/14
2 | w | 7/8/13 | 7/14/13
2 | w | 7/15/13 | 7/21/13
....
2 | w | 10/28/13 | 10/31/13
2 | m | 11/1/13 | 11/30/13
2 | m | 12/1/13 | 12/31/13
...
2 | m | 3/1/14 | 3/31/14
2 | q | 4/1/14 | 6/30/14
2 | q | 7/1/14 | 7/31/14
记录集包含每周,每季度和每月的开始和结束日期。
正在创建ID为1的输出行,ID为2的输出行不是。
我在互联网上找到的信息表明你不能两次迭代同一个记录集。我想知道是否有办法重新生成记录集或以某种方式重用它?或者我是否需要重新考虑整个设计?
赞赏,下面的脚本。
' Microsoft SQL Server Integration Services Script Component
' Write scripts using Microsoft Visual Basic 2008.
' ScriptMain is the entry point class of the script.
Imports System
Imports System.Data
Imports System.Math
Imports Microsoft.SqlServer.Dts.Pipeline.Wrapper
Imports Microsoft.SqlServer.Dts.Runtime.Wrapper
Imports System.Xml
Imports System.Data.OleDb
<Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute()> _
<CLSCompliant(False)> _
Public Class ScriptMain
Inherits UserComponent
Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)
Dim oleDA As New OleDbDataAdapter
Dim dt As New DataTable
Dim j As Integer
Dim Difference As TimeSpan
Try
If Row.mScale = "w" Then
'create 17 new rows, pull start date and enddate from the excel sheet.
oleDA.Fill(dt, Me.ReadOnlyVariables("User::WeeklyData").Value)
If dt.Rows.Count > 0 Then
'loop through and find the proper start date,
j = 0
For Each dtRow As Data.DataRow In dt.Rows
Dim dtStartDate As String = dt.Rows(j)("StartDate").ToString
Dim dfStartDate As String = Row.oStartDate.ToString
If dfStartDate = dtStartDate Then
'start here to populate the next 17 rows.
Exit For
Else
j = j + 1
End If
Next
For i = 1 To 17
With Output0Buffer
.AddRow()
.PlanID = Row.PlanID
.oStartDate = dt.Rows.Item(j)(0).ToString
.aFID = Row.aFID
.oEndDate = dt.Rows.Item(j)(1).ToString
.pScale = Row.mScale
.pCount= 1
.nwDays = Weekdays(dt.Rows.Item(j)(0), dt.Rows.Item(j)(1))
.CreateDate = Today
.ModDate = Today
j = j + 1
End With
Next
End If
End If
If Row.mScale = "m" Then
'create 7 new rows, pull start date and enddate from the excel sheet.
'where to start - the start of the month that is two months out from the project start date?
'how to add two months to the date?
oleDA.Fill(dt, Me.ReadOnlyVariables("User::MonthlyData").Value)
If dt.Rows.Count > 0 Then
'loop through and find the proper start date,
j = 0
For Each dtRow As Data.DataRow In dt.Rows
Dim dtStartDate As String = dt.Rows(j)("StartDate").ToString
Dim dfStartDate As String = Row.oStartDate.AddMonths(-2).ToString
'Subtract two months from start date.
If dfStartDate <= dtStartDate Then
'start here to populate the next 7 rows.
Exit For
Else
j = j + 1
End If
Next
For i = 1 To 7
With Output0Buffer
.AddRow()
.PlanID = Row.PlanID
.oStartDate = dt.Rows.Item(j)(0).ToString
.aFID = Row.aFID
.oEndDate = dt.Rows.Item(j)(1).ToString
'need to store this in a variable to use for the start of the quarterly dates.
.pScale = Row.mScale
.pCount= 1
'Calculate .nwDays
'NumWorkDays = dt.Rows.Item(j)(1).Subtract(dt.Rows.Item(j)(0).ToString)
'.nwDays = NumWorkDays.TotalDays
.nwDays = Weekdays(dt.Rows.Item(j)(0), dt.Rows.Item(j)(1))
.CreateDate = Today
.ModDate = Today
j = j + 1
End With
Next
End If
End If
If Row.mScale = "q" Then
'create x new rows, pull start date and enddate from the excel sheet.
oleDA.Fill(dt, Me.ReadOnlyVariables("User::QuarterlyData").Value)
If dt.Rows.Count > 0 Then
'loop through and find the proper start date,
j = 0
For Each dtRow As Data.DataRow In dt.Rows
Dim dtStartDate As String = dt.Rows(j)("StartDate").ToString
If Row.oStartDate <= dtStartDate Then
'start here to populate the next x rows until the project end date.
Exit For
Else
j = j + 1
End If
Next
While dt.Rows.Item(j)(0) <= Row.UpdateAccIDprojEndDate
With Output0Buffer
.AddRow()
.PlanID = Row.PlanID
.oStartDate = dt.Rows.Item(j)(0).ToString
.aFID = Row.aFID
'IF THIS IS WITHIN THE QUARTER WE'RE ON, THEN POPULATE WITH PROJECT END DATE.
Difference = dt.Rows.Item(j)(1).Subtract(Row.UpdateAccIDprojEndDate)
If (Row.UpdateAccIDprojEndDate < dt.Rows.Item(j)(1)) Then
.oEndDate = Row.UpdateAccIDprojEndDate
.nwDays = Weekdays(dt.Rows.Item(j)(0), Row.UpdateAccIDprojEndDate)
Else
.oEndDate = dt.Rows.Item(j)(1).ToString
.nwDays = Weekdays(dt.Rows.Item(j)(0), dt.Rows.Item(j)(1))
End If
.pScale = Row.mScale
.pCount= 1
.CreateDate = Today
.ModDate = Today
j = j + 1
End With
End While
End If
End If
Catch ex As Exception
Throw ex
Finally
'use this to do something even if the script task fails.
End Try
End Sub
Private Function Weekdays(ByRef startDate As Date, ByRef endDate As Date) As Integer
Dim numWeekdays As Integer
Dim totalDays As Integer
Dim WeekendDays As Integer
numWeekdays = 0
WeekendDays = 0
totalDays = DateDiff(DateInterval.Day, startDate, endDate) + 1
For i As Integer = 1 To totalDays
If DatePart(DateInterval.Weekday, startDate) = 1 Then
WeekendDays = WeekendDays + 1
End If
If DatePart(DateInterval.Weekday, startDate) = 7 Then
WeekendDays = WeekendDays + 1
End If
startDate = DateAdd("d", 1, startDate)
Next
numWeekdays = totalDays - WeekendDays
Return numWeekdays
End Function
End Class
答案 0 :(得分:1)
一个简单的解决方法是在脚本类中创建三个DataTable
个对象作为成员变量 - 每个,每月和每季度日期列表各一个。在脚本组件的PreExecute
子组中填充一次,然后在ProcessInputRow
子组中使用它们:
Public Class ScriptMain
Inherits UserComponent
Private _monthlyDates As New DataTable
Private _weeklyDates As New DataTable
Private _quarterlyDates As New DataTable
Public Overrides Sub PreExecute()
MyBase.PreExecute()
Dim monthlyDa As New OleDbDataAdapter
Dim weeklyDa As New OleDbDataAdapter
Dim quarterlyDa As New OleDbDataAdapter
monthlyDa.Fill(_monthlyDates, Me.Variables.MonthlyDates)
weeklyDa.Fill(_weeklyDates, Me.Variables.WeeklyDates)
quarterlyDa.Fill(_quarterlyDates, Me.Variables.QuarterlyDates);
End Sub
Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)
Dim dataTableToCheck As DataTable
Dim periodStart As Date
Dim periodEnd As Date
Dim periodFound As Boolean = False
' Choose the appropriate data table based on the mScale value
Select Case Row.mScale
Case "w"
dataTableToCheck = _weeklyDates
Case "m"
dataTableToCheck = _monthlyDates
Case "q"
dataTableToCheck = _quarterlyDates
Case Else
dataTableToCheck = Nothing
End Select
' Do whatever's appropriate with that data
' This example populates PeriodStart and PeriodEnd columns
' based on the row's StartDate and whether it's a weekly, monthly or quarterly period
If Not (dataTableToCheck Is Nothing) Then
For Each dtRow As Data.DataRow In dataTableToCheck.Rows
periodStart = CDate(dtRow("StartDate"))
periodEnd = CDate(dtRow("EndDate"))
If periodStart <= Row.StartDate And Row.StartDate <= periodEnd Then
periodFound = True
Exit For
End If
Next
If periodFound Then
Row.PeriodStart = periodStart
Row.PeriodEnd = periodEnd
Else
Row.PeriodStart_IsNull = True
Row.PeriodEnd_IsNull = True
End If
End If
End Sub
End Class