Domanda

Question:

How can I read the transformations from a DTS package programatically, preferably in C# but C++, VB.NET, Java, Python, or a SQL procedure would work as well.

Status:

I currently have some code to load a DTS package from a file:

using System;

namespace ConceptSandbox
{
    class Program
    {
        static void Main(string[] args)
        {
            String location = @"DTS.Old\GrindItemImport.dts";
            DTS.Package pkg = new DTS.Package();

            pkg.LoadFromStorageFile(location, null, null, null, null, null);
            Console.WriteLine("{0}: {1} Tasks", pkg.Name, pkg.Tasks.Count);
            for (Int32 i = 1; i <= pkg.Tasks.Count; i++)
            {
                for (Int32 j = 1; j <= pkg.Tasks.Item(i).CustomTask.Properties.Count; j++)
                {
                    Console.WriteLine("\t{0}: {1}", pkg.Tasks.Item(i).CustomTask.Properties.Item(j).Name, pkg.Tasks.Item(i).CustomTask.Properties.Item(j).Value);
                }
            }

            Console.ReadKey(true);
        }
    }
}

However, I cannot seem to drill down (or up) to get at the transformation. I've looked at the DTS object model, but it doesn't give much help and most of the resources I've found refer only how to dynamically create DTS/SSIS packages instead of how to read them.

Background:

A few years back, a segment of the company I work for did a huge refactor of a lot of code. Some of the data types were changed during this process and some of the checks on data type ranges were also lost. This data is then exported from this application to our servers and imported into our databases. The data flow is:

Data Input->CSV Export->Network->CSV Load to Temp Table->Temp to Final Table

The issue is that the export is now exporting variables that are outside the range of the database table's data types which causes failures when importing the data using DTS/SSIS packages.

I need to perform an analysis of the data type the application uses and what our databases types are in order to put some scope around how much work will be necessary to fix these issues. This is where I am currently with this analysis:

  • I can obtain the CSV filename from source
  • I can obtain the column name in the CSV file from source
  • I can link the column name in the CSV file to a variable name in the source file
  • I can obtain the data type of the variable in the source file
  • I can obtain the mappings from CSV file to the database table for SSIS packages.
  • I cannot obtain the mappings from CSV file to the database table for DTS packages.

If I knew what column in the CSV file mapped to what column in the database table, then I could use the table schema to get the type and then compare the application type to the table type to see if any action was needed for that specific file/column/table.

Just for a point of reference, there several hundred DTS packages currently still in use (eventually I will use this same process modified to automate conversion of these DTS packages to SSIS packages as well).

È stato utile?

Soluzione

For all those that come after looking for this: to get at any of the sub processes such as ActiveX scripts or DTSTransformations you must get the task, check its custom task id, and then use that to cast it to the appropriate type of DTS object before you will have access to things such as the DTS transformations. I've included the code from my sandbox project for getting the mappings below:

static void Main(string[] args)
{
    String location = @"DTS.Old\SomeDTSPackage.dts";
    DTS.Package pkg = new DTS.Package();
    DTS.Task task;
    DTS.DataPumpTask2 dataPumpTask;
    DTS.Transformation transform;
    DTS.Column source;
    DTS.Column destination;

    pkg.LoadFromStorageFile(location, null, null, null, null, null);
    Console.WriteLine("{0}", pkg.Name);

    Console.WriteLine("  TASKS");
    for (Int32 tsk = 1; tsk <= pkg.Tasks.Count; tsk++)
    {
        if (pkg.Tasks.Item(tsk).CustomTaskID == "DTSDataPumpTask")
        {
            dataPumpTask = (DTS.DataPumpTask2)pkg.Tasks.Item(tsk).CustomTask;

            Console.WriteLine("    TRANSFORMS");
            for (Int32 trans = 1; trans <= dataPumpTask.Transformations.Count; trans++)
            {
                transform = dataPumpTask.Transformations.Item(trans);
                for (Int32 col = 1; col <= transform.SourceColumns.Count && col <= transform.DestinationColumns.Count; col++)
                {
                    source = transform.SourceColumns.Item(col);
                    destination = transform.DestinationColumns.Item(col);
                    Console.WriteLine("      {0} -> {1}", source.Name.PadRight(15, ' '), destination.Name);
                }
            }
        }
    }

    Console.ReadKey(true);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top