I'm trying to produce a column 'start/length' spec document from a SSIS package that exports a DB table to a flat file. I have hit something of a brick wall in getting the Columns
property from the ConnectionManager object that handles the flat file connection. I am able to get the Columns
property, but I cannot do anything with it, as I cannot determine any type to cast it to. If I cast it to DTSProperty, I get very few useful properties on the object. If I get the property as object
, all I can determine is that it is a System.__ComObject
.
How do I retrieve the Columns property as a useful object, hopefully a collection, that I can iterate over?
Sample code:
DTSRT.Application dtap = new Application();
DTSRT.Package pkg = dtap.LoadFromDtsServer(@"\MSDB\ExportSamples", "ERISIA", null);
DTSRT.ConnectionManager ffcn = pkg.Connections["DestinationConnectionFlatFile"];
DtsProperty cols = ffcn.Properties["Columns"];
UPDATE: Ok the answer below seems like it's irrelevant in this context (though still useful in some sense, so I'll leave it). I failed to consider that the Flat File ConnectionManager has the columns available to it rather than having to go via a source/destination component with output/input columns
The value (GetValue) of the Columns property should be cast to IDTSConnectionManagerFlatFileColumns100 (or 90 if you're using the SQL Server 2005 API)
Alternatively, cast your configuration manager's InnerObject to IDTSConnectionManagerFlatFile100 which exposes a Columns property.
(These interfaces can be found in Microsoft.SqlServer.Dts.Runtime.Wrapper)
Not sure how relevant this is to your context and if you still require this, but I just did something similar, so I thought I'd share:
The code below will list all the columns of an Excel 2007 file, by building an SSIS package on the fly (You'll need to reference Microsoft.SqlServer.DTSPipelineWrap, Microsoft.SqlServer.DTSRuntimeWrap, Microsoft.SQLServer.ManagedDTS and Microsoft.SqlServer.PipelineHost).
As far as I can see, the only difference is that you'd have to interogate your loaded package to get the DataFlow task and relevant Flat File Destination component with its connection manager (in my case I created the relevant objects myself) and get its Input columns rather than Output columns.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SqlServer.Dts.Runtime;
using Microsoft.SqlServer.Dts.Pipeline.Wrapper;
namespace SSISListColumns
{
class Program
{
static void Main(string[] args)
{
// Create package
Package package = new Package();
// Create excel connection manager and set connection string
string fileName = "sampledata.xlsx";
ConnectionManager connection = package.Connections.Add("EXCEL");
connection.Properties["ConnectionString"].SetValue(connection, string.Format(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=""Excel 12.0;HDR=YES""", fileName));
// Add Data Flow task
Executable e = package.Executables.Add("STOCK:PipelineTask");
TaskHost thMainPipe = e as TaskHost;
MainPipe dataFlowTask = thMainPipe.InnerObject as MainPipe;
// Add Excel Source component
IDTSComponentMetaData100 component = dataFlowTask.ComponentMetaDataCollection.New();
component.Name = "ExcelSource";
component.ComponentClassID = "DTSAdapter.ExcelSource.2";
// Set Excel Source properties (connection manager, access mode and sheet/rowset)
CManagedComponentWrapper instance = component.Instantiate();
instance.ProvideComponentProperties();
if (component.RuntimeConnectionCollection.Count > 0)
{
component.RuntimeConnectionCollection[0].ConnectionManager = DtsConvert.GetExtendedInterface(package.Connections[0]);
component.RuntimeConnectionCollection[0].ConnectionManagerID = package.Connections[0].ID;
}
instance.SetComponentProperty("AccessMode", 0);
instance.SetComponentProperty("OpenRowset", "Sheet1$");
// Activate
instance.AcquireConnections(null);
instance.ReinitializeMetaData();
instance.ReleaseConnections();
// List output columns
var output = component.OutputCollection[0];
foreach (IDTSOutputColumn100 column in output.OutputColumnCollection)
{
Console.WriteLine(column.Name);
}
Console.ReadKey();
}
}
}