Programmatically Import Flat File Data Source into SQL Server 2008 Using SSIS’s Script Task Tool

Abstract

This article demonstrates creating a SQL Server Integration Services package that imports a text file into SQL Server database table using a Script Task component.

Requirements

Article

We begin by launching Microsoft Visual Studio and create a new Integration Services Project which is located under Business Intelligence Projects category.

After you have assigned a project name, proceed to click and drag the Script Task in Control Flow pane of the package’s toolbox.

Right click the script task and click on “Edit”

Under the Script Task Editor change the “ScriptLanguage” to “Microsoft Visual C# 2008″.

In Project Explorer, ensure the following references are added:
Microsoft.SqlServer.Dts.Design;
Microsoft.SqlServer.DTSPipelineWrap;
Microsoft.SQLServer.DTSRuntimeWrap;
Microsoft.SqlServer.ManagedDTS;
Microsoft.SqlServer.ScriptTask;
System;
System.AddIn;
System.Data;
System.Windows.Forms;
System.Xml;

Back to the code window, ensure that the following namespaces are declared:
using System;
using System.Data;
using System.Data.Sql;
using System.Data.SqlTypes;
using System.Data.SqlClient;
using Microsoft.SqlServer.Server;
using Microsoft.SqlServer.Dts.Tasks;
using Microsoft.SqlServer.Dts.Runtime;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
using RuntimeWrapper = Microsoft.SqlServer.Dts.Runtime.Wrapper;
using System.IO;

After the above declarations, proceed to creating a new application instance:
Application selectSIFISO_app = new Application();

Create package:
Package sS_pkg = new Package();

Assign relevant package name and description:
sS_pkg.Name = “Load Flat File Source into OLE DB Destination Using C#”;
sS_pkg.Description = “Programmatically create an SSIS 2008 package that loads a Flat File Source into OLE DB Destination Using Script Task’s C# language”;

Insert the Data Flow Task with appropriate name and some buffer space for processing of file (the last part is optional – you can also use default buffer allocation):
sS_pkg.Executables.Add(“STOCK:PipelineTask”);
TaskHost taskHost = sS_pkg.Executables[0] as TaskHost;
MainPipe dataFlowTask = (MainPipe)taskHost.InnerObject;
taskHost.Name = “Dynamic Data Flow Task”;
taskHost.Properties["DefaultBufferMaxRows"].SetValue(taskHost, “1000000”);

Insert the Flat File connection:
ConnectionManager connectionManagerFlatFile = sS_pkg.Connections.Add(“FLATFILE”);

You can change this path depending on where you have stored the flat file (ensure you download the attached file, see “Requirements” section above):
connectionManagerFlatFile.ConnectionString = @”C:\Temp\flat_src.txt”;

Assign name to the flat file connection:
connectionManagerFlatFile.Name = “TXT_FlatFile”;

Indicate that the flat file is delimited:
connectionManagerFlatFile.Properties["Format"].SetValue(connectionManagerFlatFile, “Delimited”);

Indicate whether the source file has column headings or not – in this case, our sample data has column headings, hence – true:
connectionManagerFlatFile.Properties["ColumnNamesInFirstDataRow"].SetValue(connectionManagerFlatFile, Convert.ToBoolean(true));

Get native Flat File connection:
RuntimeWrapper.IDTSConnectionManagerFlatFile100 connectionFlatFile = connectionManagerFlatFile.InnerObject as RuntimeWrapper.IDTSConnectionManagerFlatFile100;

Declare local string variable that will be used as part of reading the text file:
string line;

Determine the number of columns by reading the sample Flat File – line by line:

using (StreamReader file = new StreamReader(@"C:\Temp\flat_src.txt"))
{
	try
	   {
		  while ((line = file.ReadLine()) != null)
			{
			  char[] delimiters = new char[] { '|' };
			  string[] parts = line.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
			  
  for (int i = 0; i < parts.Length; i++)
	{
	   RuntimeWrapper.IDTSConnectionManagerFlatFileColumn100 flatFileCol 
	   = connectionFlatFile.Columns.Add() as RuntimeWrapper.IDTSConnectionManagerFlatFileColumn100;
	   sS_AssignColumnProperties(flatFileCol, parts[i], "|");
	}
			  //Exit file after reading the first line
			  break;
			}                
		}
	catch (Exception ex)
	   {
		   throw ex;
	   }
	finally
	   {
		   file.Close();
	   }
}

Edit the last Flat File column delimiter into NewLine instead of a Comma:
connectionFlatFile.Columns[connectionFlatFile.Columns.Count - 1].ColumnDelimiter = Environment.NewLine;

Insert Flat File source component:
IDTSComponentMetaData100 componentSource = dataFlowTask.ComponentMetaDataCollection.New();
componentSource.Name = “FlatFileSource”;
componentSource.ComponentClassID = “DTSAdapter.FlatFileSource”;

Insert source design-time instance and initialise component:
CManagedComponentWrapper instanceSource = componentSource.Instantiate();
instanceSource.ProvideComponentProperties();

Set source connection:
componentSource.RuntimeConnectionCollection[0].ConnectionManagerID = connectionManagerFlatFile.ID;
componentSource.RuntimeConnectionCollection[0].ConnectionManager = DtsConvert.ToConnectionManager90(connectionManagerFlatFile);

Reinitialize Flat File source metadata:
instanceSource.AcquireConnections(null);
instanceSource.ReinitializeMetaData();
instanceSource.ReleaseConnections();

Insert the SQL Server 2008 OLE-DB connection:
ConnectionManager connectionManagerOleDb = sS_pkg.Connections.Add(“OLEDB”);
connectionManagerOleDb.ConnectionString = string.Format(“Provider=SQLOLEDB.1;Data Source={0};Initial Catalog={1};Integrated Security=SSPI;”, “localhost”, “AdventureWorks”);
connectionManagerOleDb.Name = “OLEDB”;
connectionManagerOleDb.Description = “OLEDB Connection”;

Insert OLE-DB destination:
IDTSComponentMetaData100 componentDestination = dataFlowTask.ComponentMetaDataCollection.New();
componentDestination.Name = “OLEDBDestination”;
componentDestination.Description = “OLEDB Destination for the Flat File data load”;
componentDestination.ComponentClassID = “DTSAdapter.OLEDBDestination”;

Insert destination design-time instance and initialise component:
CManagedComponentWrapper instanceDestination = componentDestination.Instantiate();
instanceDestination.ProvideComponentProperties();

Set destination connection:
componentDestination.RuntimeConnectionCollection[0].ConnectionManagerID = connectionManagerOleDb.ID;
componentDestination.RuntimeConnectionCollection[0].ConnectionManager = DtsConvert.ToConnectionManager90(connectionManagerOleDb);

Indicates the name of the database object used to open a rowset:
instanceDestination.SetComponentProperty(“OpenRowset”, “[dbo].[sS_flatfileLoad]“);

Specifies the mode used to open the database:
instanceDestination.SetComponentProperty(“AccessMode”, 3);

Specifies options to be used with fast load. Applies only if fast load is turned on:
instanceDestination.SetComponentProperty(“FastLoadOptions”, “TABLOCK,CHECK_CONSTRAINTS”);

Indicates whether the values supplied for identity columns will be copied to the destination or not
In this case, we have set this property to false:
instanceDestination.SetComponentProperty(“FastLoadKeepIdentity”, false);

Indicates whether the columns containing null willhave null inserted in the destination or not
In this case, we have opted no to insert nulls:
instanceDestination.SetComponentProperty(“FastLoadKeepNulls”, false);

Specifies the column code page to use when code page information is unavailable from the data source
In this case we used the default – 1252:
instanceDestination.SetComponentProperty(“DefaultCodePage”, 1252);

Specifies when commits are issued during data insertion
In this case, we have opted for the default size which is set to 2147483647:
instanceDestination.SetComponentProperty(“FastLoadMaxInsertCommitSize”, 2147483647);

Indicates the number of seconds before a command times out
In this case, we have opted for the default value of 0 which indicates an infinite time-out:
instanceDestination.SetComponentProperty(“CommandTimeout”, 0);

Indicates the usage of DefaultCodePage property value when describing the character data
In this case, we have opted for the default value of false:
instanceDestination.SetComponentProperty(“AlwaysUseDefaultCodePage”, false);

Connect the Flat File source to the OLE DB Destination component:
dataFlowTask.PathCollection.New().AttachPathAndPropagateNotifications(componentSource.OutputCollection[0]
,componentDestination.InputCollection[0]);

Get input and virtual input for destination to select and map columns:
IDTSInput100 destinationInput = componentDestination.InputCollection[0];
IDTSVirtualInput100 destinationVirtualInput = destinationInput.GetVirtualInput();
IDTSVirtualInputColumnCollection100 destinationVirtualInputColumns = destinationVirtualInput.VirtualInputColumnCollection;

Reinitialize the metadata, generating exernal columns from flat file columns:
instanceDestination.AcquireConnections(null);
instanceDestination.ReinitializeMetaData();
instanceDestination.ReleaseConnections();

Select and map destination columns:
foreach (IDTSVirtualInputColumn100 virtualInputColumn in destinationVirtualInputColumns)
{
// Select column, and retain new input column
IDTSInputColumn100 inputColumn = instanceDestination.SetUsageType(destinationInput.ID,destinationVirtualInput, virtualInputColumn.LineageID, DTSUsageType.UT_READONLY);
// Find external column by name
IDTSExternalMetadataColumn100 externalColumn = destinationInput.ExternalMetadataColumnCollection[inputColumn.Name];
// Map input column to external column
instanceDestination.MapInputColumn(destinationInput.ID, inputColumn.ID, externalColumn.ID);
}

Execute the package or disable the below code if you intend running the package later:
sS_pkg.Execute();

Finally, save the package – in this case, we have opted to save the package into file system:
selectSIFISO_app.SaveToXml(@”E:\newArticle.dtsx”, sS_pkg, null);

Dts.TaskResult = (int)ScriptResults.Success;
}

In addition to the above code, you will notice that some part of the code references to the below function. This function is used to assign DTS column properties:
private static void sS_AssignColumnProperties(RuntimeWrapper.IDTSConnectionManagerFlatFileColumn100 flatFileCol, string getColName, string getDelim)
{

Assign delimiter:
flatFileCol.ColumnType = “Delimited”;
flatFileCol.ColumnDelimiter = getDelim;

Indicate column data type – in this case, all the source columns will be set to String Data Type:
flatFileCol.DataType = RuntimeWrapper.DataType.DT_STR;

Indicate column width – in this case, width of all source columns will be set to a length of 100:
flatFileCol.ColumnWidth = 100;

Assign column name:
RuntimeWrapper.IDTSName100 columnName = flatFileCol as RuntimeWrapper.IDTSName100;
columnName.Name = getColName.ToString();
}

Conclusion

It’s that simple!

You can now execute your script task and the package will be created in location you specified.

For the complete C# solution to this article, see “Requirements” section for a file name called “selectSIFISO_Flat_File_Source_into_OLE_DB_Destination_Using_CSharp.txt”.

Thanks.

Sifiso.

33 Comments

  1. Music says:

    I have followed your instructions, and have been unable to successfully run the task. I have made the following changes:

    c:\temp\
    changed to:
    C:\Data\Download\DotNetCode\c#stuff\ImportFlatFileDataSourceIntoSqlServer\

    connectionManagerOleDb.ConnectionString = string.Format(“Provider=SQLOLEDB.1;Data Source={0};Initial Catalog={1};Integrated Security=SSPI;”, “SIFISOWIN7-PC”, “AdventureWorks”);
    changed to:
    connectionManagerOleDb.ConnectionString = string.Format(“Provider=SQLOLEDB.1;Data Source={0};Initial Catalog={1};Integrated Security=SSPI;”, “MFULF4\\DSIS”, “TEMP_OUTPUT”);

    The error message is:
    Error: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. —> System.Runtime.InteropServices.COMException (0xC02020E8): Exception from HRESULT: 0xC02020E8
    at Microsoft.SqlServer.Dts.Pipeline.Wrapper.CManagedComponentWrapperClass.ReinitializeMetaData()
    at ST_94a9f0913c0a487aa85d3139c2ca8c59.csproj.ScriptMain.Main()
    — End of inner exception stack trace —
    at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
    at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
    at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
    at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
    at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
    at System.Type.InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args, CultureInfo culture)
    at Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTATaskScriptingEngine.ExecuteScript()

    I would appreciate any assistance you can provide, as I am learning on the fly.

    Thanks.

    Everett Music

    • Sifiso says:

      I will have a look and advise shortly

    • Sifiso says:

      Hi There,

      So the error you getting is about failure to re-initialise the metadata but unfortunately the error message doesn’t indicate whether was it failure to re-initialise source or destination metadata.

      In order to determine whether it’s failing on source or destination, can rather insert breakpoints inside the code and run script task in debug mode.

      Can you also ensure that you specified a correct output table in the line:

      instanceDestination.SetComponentProperty(“OpenRowset”, “[dbo].[sS_flatfileLoad]“);

      Also, on your output table, please ensure that the column names are similar to that of source file. This is because the mappings are done by column name.

      Let me know how it goes.

      Cheers.

      Sifiso

  2. Akshaya says:

    Hi,

    This code works fine for perfect input source.Meaning if i have 10 rows.

    First two rows with 4 column
    3rd and 4th rows with 2 column and
    last 6 rows with 4 column.

    Then the Destination table has only First two rows. Remaining rows are getting ignored even it is ignoring last 6 rows with 4 column also. Any idea to solve this issue. pls advice.

    Thanks in Advance
    Akshaya

    • Sifiso says:

      Hi Akshaya,

      I appreciate the feedback.

      Just recreated the error you have been getting.

      Refer to the below code, I try to determine the number of columns to insert into flat file connection by getting a count of pipe delimited columns/cells on the first row. The assumption is that if I get a total of 6 cells, then the rest of the rows should contain 6 cells regardless whether there is content or not. For example the assumption is as such:

      |heading 1|heading 2|heading 3|heading 4|heading 5|heading 6
      |a||c|d|e|f
      |a|b||d||f

      Take a look at the example I have provided above, letter b is missing from the record below headings but the count of expected cells/columns still adds up to 6.

      So I suppose my advise would be, where you don’t have entries for respective columns you should have nulls or leave empty but the column delimiters must be distributed evenly. If the file you are sourcing was outputted by some other system (i.e. SAP etc.) they normally insert null entries where there is no data but columns are distributed evenly.

      I hope this further explains the purpose of this post/approach.

      BUT, if you have a scenario where you getting data with incompatible number of columns, then either you put some check to have that rectified before running this script. Another way would to loop through individual row, create an output table based on number of columns sourced. Meaning in your example of 10 rows, you will have 10 different tables. Or you can have two output table but prior to looping each row, you will have to check the count of columns and compare to previous row such that when you get to the rows with 2 columns you output to another table – or you programmatically insert a column with null to fill the missing 2 columns.

      So, yes, there are definitely ways to deal with the issue you raised but it can be expensive and time-consuming.

      You know what, come to think of it, I will create another post that will address inserting null entries where the source data columns are varying.

      watch this space. thanks again for your feedback and apologies for a mouthful response.

      using (StreamReader file = new StreamReader(@”C:\Temp\flat_src.txt”))
      {
      try
      {
      while ((line = file.ReadLine()) != null)
      {
      char[] delimiters = new char[] { ‘|’ };
      string[] parts = line.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);

      for (int i = 0; i < parts.Length; i++)
      {
      RuntimeWrapper.IDTSConnectionManagerFlatFileColumn100 flatFileCol
      = connectionFlatFile.Columns.Add() as RuntimeWrapper.IDTSConnectionManagerFlatFileColumn100;
      sS_AssignColumnProperties(flatFileCol, parts[i], “|”);
      }
      //Exit file after reading the first line
      break;
      }
      }
      catch (Exception ex)
      {
      throw ex;
      }
      finally
      {
      file.Close();
      }

      }

  3. Sonal says:

    Hey there,

    I have successfully used your code. Works fine for me…thanks a lot.
    Can you please suggest some approach for using Unpivot data transformation programmatically. Thanks again….have a nice one…

  4. Ravi says:

    Hi,

    The code you have posted is nice one. I have used your code works fine for me. But i have the flat file column names and data with double quotes. Flat file likes this below,

    “ID”,”FirstName”,”LastName”
    “1”,”Name1″,”Name2″

    I would appreciate any assistance you can provide, thanks in advance.

    Thanks,
    Ravi

  5. Sifiso says:

    hi Ravi,

    replace the stream reader script with the one below. I have replaced the pipe delimiter with comma and did a substring. I have test ran it and it runs fine. it’s just that the row data still have double quotes – that’s because I break after reading 1 line of record. You might have to insert a data conversion/derived component to remove the quotes.

    using (StreamReader file = new StreamReader(@”C:\Temp\flat_src.txt”))
    {
    try
    {
    while ((line = file.ReadLine()) != null)
    {
    char[] delimiters = new char[] { ‘,’ };
    string[] parts = line.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
    string frmt=””;

    for (int i = 0; i < parts.Length; i++)
    {
    RuntimeWrapper.IDTSConnectionManagerFlatFileColumn100 flatFileCol = connectionFlatFile.Columns.Add() as RuntimeWrapper.IDTSConnectionManagerFlatFileColumn100;
    frmt = parts[i].Substring(1, (parts[i].Length – 2));
    sS_AssignColumnProperties(flatFileCol, frmt, “,”);
    }
    //Exit file after reading the first line
    break;
    }
    }
    catch (Exception ex)
    {
    throw ex;
    }
    finally
    {
    file.Close();
    }
    }

    • Ravi says:

      Hi,

      Thanks for your help. Working fine now :).

      Thanks,
      Ravi

    • Ravi says:

      Hi,
      I have one more clarification. In my flat file, i have some columns filled with blank values. Here is a sample of it:

      “column1″,”column2″,”column3″,”column4″
      “1”,”John”,”10″,”09/01/2012 12:00:00 AM”
      “2”,”Mark”,””,”09/01/2012 12:00:00 AM”
      “3”,”Steve”,””,””

      In the above sample, consider the third row containing data (“3″,”Steve”,””,””). In this data, column3 and column4 are empty and in database table, the corresponding columns are of data type numeric and date/time respectively. These columns are declared as nullable as well. But while inserting this data using the above mentioned code, i am getting an error similar to one mentioned below:

      Data conversion failed. The data conversion for column “Column3″ returned status value 2 and status text “The value could not be converted because of a potential loss of data.”.

      Can you tell me how to convert string.empty from the flat file as NULL while inserting into database?

      Thanks in advance for your help!

      Regards,
      Ravi

      • Sifiso says:

        Hi,

        Why don’t you stage the data first by importing all data into a table with varchar data types columns?

        You can then transform/convert it using T-SQL.

        I just think that might be easier, what do you think?

        Regards,

        Sifiso

  6. Subham says:

    Great Article. Thanks a lot for posting this…

  7. vasu says:

    Hi All,

    Is there any solution by suing Excel files.

    Thanks
    vasu

  8. Mostard says:

    Hi Sifiso

    Great article ! Many thanks for posting.

    I’m trying to design the package so it contains a “create table” task first, then a dataflow, fully depending on the flat file contents/layout.

    It find your code help me a lot, but seems to me it actually expects the target table to exist already, which is not the case for me.

    It fails at this point:

    instanceDestination.AcquireConnections(null);

    … because of course the table specified as destination in the line

    instanceDestination.SetComponentProperty(“OpenRowset”, “[dbo].[sS_flatfileLoad]“);

    … does not exist in my case.

    Is there a way to, using the same column info derived from the file file, explicitly set the metadata instead of actualling connecting there, and calling ReinitializeMetaData()?

    TargetComponentInstance.ReinitializeMetaData()

    Thanks again!

    Mostard.

  9. vishal says:

    hey i want a ssis to create package that can create a table and insert all the data from flat file
    with delimeters as [tab]

    can you please tell me the code .

  10. vishal says:

    hey i want a ssis to create package that can create a table and insert all the data from flat file
    with delimeters as [tab]

    can you please tell me the code .

    c# code
    that can help .

  11. JakkiM says:

    Do you happen to have anything like this for 2012?

  12. brad says:

    Hi, I am trying to run this code (below) and I get error on the destination component, at _destinationInstance.ReinitializeMetaData();

    and I have found that this is when I have this line: _destinationInstance.SetComponentProperty(“AccessMode”, “0”);

    I get an hresult exception.

    I have tried all other access modes and nothing works. If I get rid of the accessMode line, the package runs with no errors but nothing is pushed in to the SQL Table.

    Any ideas?
    Thanks in advance.

    using System;
    using System.Linq;
    using Microsoft.SqlServer.Dts.Runtime.Wrapper;
    using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
    using Microsoft.SqlServer.Dts.Runtime;
    using System.IO;
    using System.Collections.Generic;
    using System.Data.Common;
    using System.Reflection;
    using Microsoft.VisualBasic.FileIO;
    using Microsoft.SqlServer.Dts;

    namespace ssis
    {
    public class FlatFileColumnReader
    {
    public List Columns(string path, char delimiter, FieldType ft)
    {
    var tfp = new TextFieldParser(path)
    {
    TextFieldType = ft
    };

    tfp.Delimiters = new string[] {delimiter.ToString()};
    return tfp.ReadFields().ToList();
    }
    }

    public class ssis_run
    {
    public static Microsoft.SqlServer.Dts.Runtime.Package Generate(Microsoft.SqlServer.Dts.Runtime.Application app)
    {
    Microsoft.SqlServer.Dts.Runtime.Package _package;
    Executable _dataFlowTask;
    IDTSComponentMetaData100 _dataSource;
    IDTSComponentMetaData100 _dataDest;
    CManagedComponentWrapper _sourceInstance;
    CManagedComponentWrapper _destinationInstance;
    ConnectionManager _conMgrSource;
    ConnectionManager _conMgrDest;

    _package = new Microsoft.SqlServer.Dts.Runtime.Package();
    _package.DelayValidation = true;
    _dataFlowTask = _package.Executables.Add(“STOCK:PipelineTask”);
    MainPipe pipe = (MainPipe)((Microsoft.SqlServer.Dts.Runtime.TaskHost)_dataFlowTask).InnerObject;
    //pipe.ComponentMetaDataCollection.RemoveAll();

    /// Create connections
    _conMgrSource = _package.Connections.Add(“FLATFILE”);
    _conMgrSource.Properties["Format"].SetValue(_conMgrSource, “Delimited”);
    _conMgrSource.Properties["Name"].SetValue(_conMgrSource, “Flat File Connection”);
    _conMgrSource.Properties["ConnectionString"].SetValue(_conMgrSource, @”G:\DATA\VIS\Rowing\World Racing Performance Prediction Database_01_JUNE_2012 – Copy.csv”);
    _conMgrSource.Properties["ColumnNamesInFirstDataRow"].SetValue(_conMgrSource, true);
    _conMgrSource.Properties["HeaderRowDelimiter"].SetValue(_conMgrSource, “{CR}{LF}”);
    //_conMgrSource.Properties["HeaderRowDelimiter"].SetValue(_conMgrSource, “\r\n”);
    _conMgrSource.Properties["RowDelimiter"].SetValue( _conMgrSource, “{CR}{LF}” );
    _conMgrSource.Properties["TextQualifier"].SetValue(_conMgrSource, “\””);
    _conMgrSource.Properties["DataRowsToSkip"].SetValue(_conMgrSource, 0);

    _conMgrDest = _package.Connections.Add(“OLEDB”);
    _conMgrDest.ConnectionString = @”Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=RowingRaces;Data Source=localhost”;
    //_conMgrDest.ConnectionString = @”Data Source=localhost;Initial Catalog=RowingRaces;Provider=SQLNCLI10.1;Integrated Security=SSPI;Auto Translate=False;”;
    _conMgrDest.Name = “OLE DB Connection”;
    _conMgrDest.Description = “OLE DB Connection”;
    _conMgrDest.Properties["RetainSameConnection"].SetValue(_conMgrDest, true);

    /// Create the columns in the flat file connection
    var flatFileConnection = _conMgrSource.InnerObject as IDTSConnectionManagerFlatFile100;
    var fileColumns = new FlatFileColumnReader().Columns( @”G:\DATA\VIS\Rowing\World Racing Performance Prediction Database_01_JUNE_2012.csv”, ‘,’, FieldType.Delimited);
    for (int i = 0; i < fileColumns.Count; i++)
    {
    var column = flatFileConnection.Columns.Add();
    //column.ColumnDelimiter = (i == fileColumns.Count – 1) ? "\r\n" : ",";
    column.ColumnDelimiter = (i == fileColumns.Count – 1) ? "{CR}{LF}" : ",";
    column.TextQualified = true;
    column.ColumnType = "Delimited";
    column.DataType = DataType.DT_TEXT;
    column.DataPrecision = 0;
    column.DataScale = 0;
    ( (IDTSName100)column ).Name = fileColumns[i];
    }

    /// Create Data Flow Components
    _dataSource = pipe.ComponentMetaDataCollection.New();
    _dataSource.Name = "Flat File Source";
    _dataSource.ComponentClassID = app.PipelineComponentInfos["Flat File Source"].CreationName;
    _dataSource.ValidateExternalMetadata = false;
    _sourceInstance = _dataSource.Instantiate();
    _sourceInstance.ProvideComponentProperties();
    _dataSource.RuntimeConnectionCollection[0].ConnectionManager = DtsConvert.GetExtendedInterface(_conMgrSource);
    _dataSource.RuntimeConnectionCollection[0].ConnectionManagerID = _conMgrSource.ID;
    _sourceInstance.AcquireConnections(null);
    _sourceInstance.ReinitializeMetaData();
    _sourceInstance.ReleaseConnections();

    _dataDest = pipe.ComponentMetaDataCollection.New();
    //_dataDest.Name = "Sql Server Destination";
    //_dataDest.ComponentClassID = app.PipelineComponentInfos["SQL Server Destination"].CreationName;
    _dataDest.Name = "OLE DB Destination";
    _dataDest.ComponentClassID = app.PipelineComponentInfos["OLE DB Destination"].CreationName;
    _dataDest.ValidateExternalMetadata = true;
    _destinationInstance = _dataDest.Instantiate();
    _destinationInstance.ProvideComponentProperties();
    //_destinationInstance.SetComponentProperty("BulkInsertTableName", "[races]");
    _dataDest.RuntimeConnectionCollection[0].ConnectionManager = DtsConvert.GetExtendedInterface(_conMgrDest);
    _dataDest.RuntimeConnectionCollection[0].ConnectionManagerID = _conMgrDest.ID;
    _destinationInstance.SetComponentProperty("OpenRowset", "[dbo].[races]");
    _destinationInstance.SetComponentProperty("AccessMode", "0");
    _destinationInstance.AcquireConnections(null);
    _destinationInstance.ReinitializeMetaData();
    _destinationInstance.ReleaseConnections();

    var path = pipe.PathCollection.New();
    path.AttachPathAndPropagateNotifications(_dataSource.OutputCollection[0], _dataDest.InputCollection[0]);

    //bo
    IDTSInput100 destInput = _dataDest.InputCollection[0];
    IDTSVirtualInput100 destVirInput = destInput.GetVirtualInput();
    IDTSInputColumnCollection100 destInputCols = destInput.InputColumnCollection;
    IDTSExternalMetadataColumnCollection100 destExtCols = destInput.ExternalMetadataColumnCollection;
    IDTSOutputColumnCollection100 sourceColumns = _dataSource.OutputCollection[0].OutputColumnCollection;

    foreach (IDTSOutputColumn100 outputCol in sourceColumns)
    {
    IDTSExternalMetadataColumn100 extCol = (IDTSExternalMetadataColumn100)destExtCols[outputCol.Name];
    if (extCol != null)
    {
    destVirInput.SetUsageType(outputCol.ID, DTSUsageType.UT_READONLY);
    IDTSInputColumn100 inputCol = destInputCols.GetInputColumnByLineageID(outputCol.ID);
    if (inputCol != null)
    {
    _destinationInstance.MapInputColumn(destInput.ID, inputCol.ID, extCol.ID);
    }
    }
    }
    //bo

    //bo commented out
    //var virtualInput = _dataDest.InputCollection[0].GetVirtualInput();
    //foreach (IDTSVirtualInputColumn100 column in virtualInput.VirtualInputColumnCollection)
    //{
    // _destinationInstance.SetUsageType(_dataDest.InputCollection[0].ID, virtualInput, column.LineageID, DTSUsageType.UT_READONLY);
    //}

    ///// MapColumns();
    //foreach (IDTSInputColumn100 inputColumn in _dataDest.InputCollection[0].InputColumnCollection)
    //{
    // var outputColumn = _dataDest.InputCollection[0].ExternalMetadataColumnCollection[inputColumn.Name];
    // outputColumn.Name = inputColumn.Name;
    // _destinationInstance.MapInputColumn(_dataDest.InputCollection[0].ID, inputColumn.ID, outputColumn.ID);
    //}
    //bo commented out
    _package.Validate(_package.Connections, null, null, null);
    return _package;
    }
    }
    }

  13. Smita says:

    Hi,

    Thank you for this code. It works well, but I need the code for fixed width as well as delimiter. configuration for column type will get from the database. please let me know how to perform this task.

  14. Floyd says:

    Hi Sifiso

    I am rather new to all this so am struggling with a flatfile. My flatfile has no headers but follows a strict schema and the structure illustrated below:

    |InvoiceDetail ||a||c|d|e|f
    |RecordType 1||a||c|d|e|f
    |RecordType 1||a||c|d|e|f
    |RecordType 1||a||c|d|e|f
    |RecordType 1||a||c|d|e|f
    |RecordType 2||a|b||d||f
    |RecordType 2||a|b||d||f
    |RecordType 2||a|b||d||f
    |RecordType 3||c||a|d|e|f
    |RecordType 3||c||a|d|e|f
    |RecordType 3||c||a|d|e|f
    |RecordType 3||c||a|d|e|f
    |RecordType 4||y|x||d|a|x
    |RecordType 4||y|x||d|a|x
    |RecordType 4||y|x||d|a|x
    |InvoiceSummary |||a||c|d|e|f

    I need to upload the file to six separate tables as follows:

    InvoiceDetail -> dbo.Invoice (1 row only)
    RecordType 1 -> dbo.ProductCharge(250k rows)
    RecordType 2 -> dbo.Event (100 rows)
    RecordType 3 -> dbo.Adjustment(100 rows)
    RecordType 4 -> dbo.RC Adjustment(100 rows)
    InvoiceSummary -> dbo.BillSummary(1 row only)

    My scripting skills are virtually nonexistent so any assistance you can provide will be greatly appreciated.

    Many thanks

    Floyd

  15. shreeya says:

    I want a ssis to create package that can create a table and insert all the data from flat file
    with delimeters as [tab]

    • Sifiso says:

      hi, have you had a look at this blog? there is a similar article that I published about same topic.

      • Iyappan says:

        Hi,

        We have script task based on above code. Initially i had 7 columns in the file and run the package , it was successfully loaded records into staging table with out any issues.

        After some time , i have added 10 columns in the file and run the package , it does not loading any records into staging table with out an error.

        It looks strange , we checked many times the number of delimiters, file data and no chunk charaters added.

        Once again , if i put back old file with 7 columns, it loads the data into staging table.

      • Iyappan says:

        Hi,

        We have script task based on above code. Initially i had 7 columns in the file and run the package , it was successfully loaded records into staging table with out any issues.

        After some time , i have added 10 columns in the file and run the package , it does not loading any records into staging table with out an error.

        It looks strange , we checked many times the number of delimiters, file data and no chunk charaters added.

        Once again , if i put back old file with 7 columns, it loads the data into staging table.

        Can anyone please help on this?

Leave a comment

%d bloggers like this: