Quantcast
Channel: SQL Server Integration Services forum
Viewing all articles
Browse latest Browse all 24688

ReinitializeMetaData() method giving error while iterating through dataflow components in dynamic package

$
0
0

Hi,

I am creating a package programatically in a Script Task inside a package. This package  has 1 data flow task created programmatically which is supposed to have 2 sources & 2 destinations running in parallel. Source & destination tables are identical.

I have written below code for the same. The FOR loop works fine for 1st iteration but it give me error on 2nd iteration at "oledbDestinationInstance[i].ReinitializeMetaData();" which is just after setting the AccessMode of destination. The error says

Error: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Runtime.InteropServices.COMException (0xC0202040): Exception from HRESULT: 0xC0202040
   at Microsoft.SqlServer.Dts.Pipeline.Wrapper.CManagedComponentWrapperClass.ReinitializeMetaData()

I dont find any other information related to error. Due to which I am unable to understand the cause of error. I tried to search for this over many sites but didnt find any solution yet.

I will appreciate if anyone can help me.

Code:-

#region actual data flow task code
                string SrcConnection = Dts.Connections["Source"].Name;
                string DestConnection = Dts.Connections["Destination"].Name;
                Connections connections = Dts.Connections;
                string SrcTables = "dbo.DimAccount, dbo.DimCurrency";
                string DestTables = "dbo.DimAccount_Test, dbo.DimCurrency_Test";
                int countOfTables = 0;
                string[] srcTablesArray;
                string[] destTablesArray;
                string sourceQuery = string.Empty;
                IDTSComponentMetaData100[] oledbSource;
                IDTSComponentMetaData100[] oledbDestination;
                CManagedComponentWrapper[] oledbSourceInstance;
                CManagedComponentWrapper[] oledbDestinationInstance;
                IDTSPath100[] pathSourceToDestination;
                IDTSInput100[] destInput;
                IDTSVirtualInput100[] destVirtualInput;
                //TO access the package we need to have an Applicatoin object
                Microsoft.SqlServer.Dts.Runtime.Application app = new Microsoft.SqlServer.Dts.Runtime.Application();
                Package pkg = new Package();
                //Getting the 1st executable of the loaded package
                TaskHost thMainTask = (Microsoft.SqlServer.Dts.Runtime.TaskHost)pkg.Executables.Add("DTS.Pipeline");
                //Naming the executable
                thMainTask.Name = "DynamicDataFlowTask";
                //attaching a Main Pipeline (DataFlowTask) as an inner object of main executable
                MainPipe dataFlowTask = (MainPipe)thMainTask.InnerObject;
                //making sure there is no metadata available in Main Pipeline (Data Flow Task)
                dataFlowTask.ComponentMetaDataCollection.RemoveAll();
                #region Create source connection
                //Create source connection
                ConnectionManager sourceConnection = pkg.Connections.Add("OLEDB");
                //setting up the selected connection in source drop down as source
                sourceConnection.Name = SrcConnection;
                //assigning connection string of selected connection manager as source 
                for (int i = 0; i < connections.Count; i++)
                {
                    if (connections[i].Name == SrcConnection)
                    {
                        sourceConnection.ConnectionString = connections[i].ConnectionString;
                        break;
                    }
                }
                #endregion
                #region Create destination connection
                //Create destination connection
                ConnectionManager destinationConnection = pkg.Connections.Add("OLEDB");
                //setting up the selected connection in destination drop down as destination
                destinationConnection.Name = DestConnection;
                //assigning connection string of selected connection manager as destination 
                for (int i = 0; i < connections.Count; i++)
                {
                    if (connections[i].Name == DestConnection)
                    {
                        destinationConnection.ConnectionString = connections[i].ConnectionString;
                        break;
                    }
                }
                #endregion
                #region code that can be repeated for many sources and destinations 
                //Get table names splitted and count of them
                srcTablesArray = this.SplitTables(SrcTables);
                countOfTables = srcTablesArray.Length;
                destTablesArray = this.SplitTables(DestTables);
                //Defining length of each array object with sourceTable count 
                oledbSource = new IDTSComponentMetaData100[countOfTables];
                oledbDestination = new IDTSComponentMetaData100[countOfTables];
                oledbSourceInstance = new CManagedComponentWrapper[countOfTables];
                oledbDestinationInstance = new CManagedComponentWrapper[countOfTables];
                pathSourceToDestination = new IDTSPath100[countOfTables];
                destInput = new IDTSInput100[countOfTables];
                destVirtualInput = new IDTSVirtualInput100[countOfTables];
                for (int i = 0; i < countOfTables; i++)
                {
                    #region setup source component/s
                    //Setup source component in DataFlowTask
                    oledbSource[i] = dataFlowTask.ComponentMetaDataCollection.New();
                    oledbSource[i].ComponentClassID = "DTSAdapter.OLEDBSource";     //The type of Transformation
                    oledbSource[i].ValidateExternalMetadata = true;
                    //Get the design time instance of source component
                    oledbSourceInstance[i] = oledbSource[i].Instantiate();
                    //Initialize the source component
                    oledbSourceInstance[i].ProvideComponentProperties();
                    oledbSource[i].Name = "OLEDB Source " + i;   //Addinng the counter to create distinct task name
                    //now setup the source connection properties of source component in DataFlowTask
                    if (oledbSource[i].RuntimeConnectionCollection.Count > 0)
                    {
                        oledbSource[i].RuntimeConnectionCollection[0].ConnectionManagerID = sourceConnection.ID;
                        oledbSource[i].RuntimeConnectionCollection[0].ConnectionManager = DtsConvert.GetExtendedInterface(sourceConnection);
                    }
                    //Set the custom properties of the Source like Query/Table Names 
                    sourceQuery = "SELECT * FROM " + srcTablesArray[i].ToString();
                    oledbSourceInstance[i].SetComponentProperty("AccessMode", 2);
                    oledbSourceInstance[i].SetComponentProperty("SqlCommand", sourceQuery);
                    //Acquire Connections, reinitialize the component and then release the connection
                    oledbSourceInstance[i].AcquireConnections(null);
                    oledbSourceInstance[i].ReinitializeMetaData();
                    oledbSourceInstance[i].ReleaseConnections();
                    #endregion
                    #region setup destination component/s
                    //setup destination component in DataFlowTask
                    oledbDestination[i] = dataFlowTask.ComponentMetaDataCollection.New();
                    oledbDestination[i].ComponentClassID = "DTSAdapter.OLEDBDestination";   //The type of Transformation
                    oledbDestination[i].ValidateExternalMetadata = true;
                    //get the design time instance of destination component
                    oledbDestinationInstance[i] = oledbDestination[i].Instantiate();
                    //Initialize the destination component
                    oledbDestinationInstance[i].ProvideComponentProperties();
                    oledbDestination[i].Name = "OLEDB Destination " + i;    //Addinng the counter to create distinct task name
                    //now setup the destination connection properties of destination component in DataFlowTask
                    if (oledbDestination[i].RuntimeConnectionCollection.Count > 0)
                    {
                        oledbDestination[i].RuntimeConnectionCollection[0].ConnectionManagerID = destinationConnection.ID;
                        oledbDestination[i].RuntimeConnectionCollection[0].ConnectionManager = DtsConvert.GetExtendedInterface(destinationConnection);
                    }
                    //Set the custom properties of the Source like Query/Table Names 
                    oledbDestinationInstance[i].SetComponentProperty("AccessMode", 3);
                    oledbDestinationInstance[i].SetComponentProperty("OpenRowset", destTablesArray[i]);
                    //oledbDestinationInstance[i].SetComponentProperty("FastLoadKeepIdentity", true);
                    //Acquire Connections, reinitialize the component 
                    oledbDestinationInstance[i].AcquireConnections(null);
                    oledbDestinationInstance[i].ReinitializeMetaData();
                    oledbDestinationInstance[i].ReleaseConnections();
                    #endregion
                    #region TUNNEL setup between source & destination
                    //Creating tunnel/path between source and destination i.e. connecting source & destination
                    pathSourceToDestination[i] = dataFlowTask.PathCollection.New();
                    pathSourceToDestination[i].AttachPathAndPropagateNotifications(oledbSource[i].OutputCollection[0], oledbDestination[i].InputCollection[0]);
                    //Iterate through the inputs of the component
                    destInput[i] = oledbDestination[i].InputCollection[0];
                    //Get the virtual input column collection for the input
                    destVirtualInput[i] = destInput[i].GetVirtualInput();
                    //oledbDestinationInstance[i].ReinitializeMetaData();
                    //Iterate through the virtual column collection
                    foreach (IDTSVirtualInputColumn100 vColumn in destVirtualInput[i].VirtualInputColumnCollection)
                    {
                        //Call the SetUsageType method of the design time instance of the component
                        IDTSInputColumn100 vCol = oledbDestinationInstance[i].SetUsageType(destInput[i].ID, destVirtualInput[i], vColumn.LineageID, DTSUsageType.UT_READONLY);
                        //Creating the mapping between columns
                        oledbDestinationInstance[i].MapInputColumn(destInput[i].ID, vCol.ID, destInput[i].ExternalMetadataColumnCollection[vColumn.Name].ID);
                    }
                    //After mapping the columns re-initialize the metadata for destination and release the connection                    
                    oledbDestinationInstance[i].AcquireConnections(null);
                    oledbDestinationInstance[i].ReinitializeMetaData();
                    oledbDestinationInstance[i].ReleaseConnections();
                    #endregion
                }
                //Execute the package
                DTSExecResult pkgResult = pkg.Execute();
                //Return the execution result
                executionResult = pkgResult;
                if (executionResult == DTSExecResult.Success)
                {
                    Dts.TaskResult = (int)ScriptResults.Success;
                }
                else
                {
                    Dts.TaskResult = (int)ScriptResults.Failure;
                }
                #endregion
                #endregion

Thank you.

Mr myName





Viewing all articles
Browse latest Browse all 24688

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>