So keeping my focus on SSIS Script Component as Source I show another example. Mostly Script component is needed when source is Flat file and we need to retain the previous record value(s) to be used in the next record(s). Keeping this in mind I present the scenario:
The source file layout
1,1
2,1
3,0
4,1
5,0
6,0
7,1
Requirement: Add a third column to data and the values need to be set base on the existing 2 columns. If Column 2 value 1 set column 3 as Column 1, else set Column 3 value to the Column 1 value of the previous record.
Expected Output:
Col1 Col2 Col3
1 1 1
2 1 2
3 0 2
4 1 4
5 0 4
6 0 4
7 1 7
For details on setting up the Script Component as source check out this post.
Check out the code:
C#
using System;
using System.Data;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using Microsoft.SqlServer.Dts.Runtime.Wrapper;
//Add this Namespace for IO Operations
using System.IO;
[Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute]
public class ScriptMain : UserComponent
{
//StramReader to read the input file stream
private StreamReader textReader;
//String to save the source file path
private string SrcFilePath;
public override void AcquireConnections(object Transaction)
{
IDTSConnectionManager100 connMgr = this.Connections.Conn;
SrcFilePath = (string)connMgr.AcquireConnection(null);
}
public override void PreExecute()
{
base.PreExecute();
//Set the textReader at the PreExecute Phase so that we donot initialize it for each record.
textReader = new StreamReader(SrcFilePath);
}
public override void CreateNewOutputRows()
{
string nextLine;
string[] columns;
string lastCol="";
char[] delimiters;
delimiters = ",".ToCharArray();
//Read next line from the file to the string variable
nextLine = textReader.ReadLine();
//Read the file till nextLine variable is not NULL ie. EOF
while (nextLine != null)
{
//Split the records by commas to later extract the data and not the column Name in each record.
columns = nextLine.Split(delimiters);
if(columns[1]=="1")
lastCol = columns[0];
this.OutputBuffer.AddRow();
this.OutputBuffer.Col1 = columns[0];
this.OutputBuffer.Col2 = columns[1];
this.OutputBuffer.Col3 = lastCol;
nextLine = textReader.ReadLine();
}
}
public override void PostExecute()
{
base.PostExecute();
//Close the Text reader once the file has been read in the PostExecute Phase.
textReader.Close();
}
}
vb.NET
Imports System
Imports System.Data
Imports System.Math
Imports Microsoft.SqlServer.Dts.Pipeline.Wrapper
Imports Microsoft.SqlServer.Dts.Runtime.Wrapper
'Add this Namespace for IO Operations
Imports System.IO
<Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute()> _
<CLSCompliant(False)> _
Public Class ScriptMain
Inherits UserComponent
'StramReader to read the input file stream
Private textReader As StreamReader
'String to save the source file path
Private SrcFilePath As String
Public Overrides Sub AcquireConnections(ByVal Transaction As Object)
Dim connMgr As IDTSConnectionManager100 = Me.Connections.Conn
SrcFilePath = DirectCast(connMgr.AcquireConnection(Nothing), String)
End Sub
Public Overrides Sub PreExecute()
MyBase.PreExecute()
'Set the textReader at the PreExecute Phase so that we donot initialize it for each record.
textReader = New StreamReader(SrcFilePath)
End Sub
Public Overrides Sub CreateNewOutputRows()
Dim nextLine As String
Dim columns As String()
Dim lastCol As String = ""
Dim delimiters As Char()
delimiters = ",".ToCharArray()
'Read next line from the file to the string variable
nextLine = textReader.ReadLine()
'Read the file till nextLine variable is not NULL ie. EOF
While nextLine IsNot Nothing
'Split the records by commas to later extract the data and not the column Name in each record.
columns = nextLine.Split(delimiters)
If columns(1) = "1" Then
lastCol = columns(0)
End If
' Add new row to the output
Me.OutputBuffer.AddRow()
' Assign values to the output column
Me.OutputBuffer.Col1 = columns(0)
Me.OutputBuffer.Col2 = columns(1)
' Assign value to Col3 from the value stored in the lastCol variable
Me.OutputBuffer.Col3 = lastCol
nextLine = textReader.ReadLine()
End While
End Sub
Public Overrides Sub PostExecute()
MyBase.PostExecute()
'Close the Text reader once the file has been read in the PostExecute Phase.
textReader.Close()
End Sub
End Class
Output: