Getting column name from PipelineBuffer in Script Component in SSIS 2012

jymbo picture jymbo · Mar 30, 2014 · Viewed 8.6k times · Source

I'm trying to get the column name and index from the PipelineBuffer in my script component transformation is SSIS and add them to a Hashtable. I know this is possible if I change my class from:public class ScriptMain : UserComponent to ScriptMain : PipelineComponent and use this code:

public override void ProcessInput(int InputID, Microsoft.SqlServer.Dts.Pipeline.PipelineBuffer Buffer)
{
    inputBuffer = Buffer;
    hash = new Hashtable();
    IDTSInput100 i = ComponentMetaData.InputCollection.GetObjectByID(InputID);
    foreach (IDTSInputColumn100 col in i.InputColumnCollection)
    {
        int colIndex = BufferManager.FindColumnByLineageID(i.Buffer, col.LineageID);
        hash.Add(col.Name, colIndex);
    }
}

However; when I do this I can no longer override: public override void Input0_ProcessInputRow(Input0Buffer Row) Since this is not available in the PipelineComponent class and I can no longer access my connection managers by simply calling something like this: IDTSConnectionManager100 connMgr = this.Connections.DbConnection; From what I can see the BufferManager is not available in the UserComponent class. Is there a way to accomplish this using the UserComponent?

Answer

jymbo picture jymbo · Mar 31, 2014

Buddy of mine worked through this with me. You can get the name of the column coming in the script buffer like this:

public override void Input0_ProcessInputRow(Input0Buffer inputBufferRow)
     {
    foreach (IDTSInputColumn100 column in this.ComponentMetaData.InputCollection[0].InputColumnCollection)
            { 
              PropertyInfo columnValue = inputBufferRow.GetType().GetProperty(column.Name);
            }
       }

You can get the column index and name in the script buffer by using reflection in the script component and loading them into a filtered list like this:

IList<string> propertyList = new List<string>();
                    var properties = typeof(Input0Buffer).GetProperties();
                    foreach (var property in properties)
                    {
                        if (!property.Name.EndsWith("_IsNull"))
                            propertyList.Add(property.Name);
                    }

You can then access the list to get the index value in the script buffer using the name of the PropertyInfo object:

int index = (propertyList.IndexOf(columnValue.Name));

In order to then link this up with the index of the column in the input pipeline buffer you need to create a class attribute:

int[] BufferColumnIndexes; 

Then override ProcessInput and add the indexes from the input pipeline buffer that map to the script buffer indexes:

public override void ProcessInput(int InputID, Microsoft.SqlServer.Dts.Pipeline.PipelineBuffer Buffer)
    {
        inputBuffer = Buffer;
        BufferColumnIndexes = GetColumnIndexes(InputID);
        base.ProcessInput(InputID, Buffer);
    }

Now to link these up:

int index = (propertyList.IndexOf(columnValue.Name)); //index in script buffer
int index2 = (BufferColumnIndexes[index]); //index in input pipeline buffer