Error adding duplicate key to dictionary in script task

the script runs forever, but unexpectedly started to crash, stating

Error: 0x0 at (SCR) GetLineageIDs, ProcessDataFlowTask error:: An item with the same key has already been added.
   at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   at ST_b90e02c5aa5e4a7a992a1a75c6255cfa.ScriptMain.ProcessDataFlowTask(TaskHost currentDataFlowTask)

The goal is for get lineID to match the actual column name in my SSIS package (2012, so there is no 2016 line functionality).

It seems to me that I'm trying to add a key that has already been added to my dictionary in the following script, I'm not sure how and why it suddenly started erroneously, the full script below. I think I need some kind of block ifin my method ProcessDataFlowTask, would any pointers be gratefully received and an explanation of why a repeated key error suddenly appears?

namespace ST_b90e02c5aa5e4a7a992a1a75c6255cfa
{
    /// <summary>
    /// ScriptMain is the entry point class of the script.  Do not change the name, attributes,
    /// or parent of this class.
    /// </summary>
    [Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
    public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
    {


        Dictionary<int, string> lineageId = null;

        public void Main()
        {

            try
            {
                // Grab the executables so we have to something to iterate over, and initialize our lineageIDs list
                // Why the executables?  Well, SSIS won't let us store a reference to the Package itself...
                Dts.Variables["User::execsObj"].Value = ((Package)Dts.Variables["User::execsObj"].Parent).Executables;
                Dts.Variables["User::lineageIds"].Value = new Dictionary<int, string>();
                lineageId = (Dictionary<int, string>)Dts.Variables["User::lineageIds"].Value;

                Executables execs = (Executables)Dts.Variables["User::execsObj"].Value;

                ReadExecutables(execs);

                Dts.TaskResult = (int)ScriptResults.Success;

            }
            catch (Exception ex)
            {
                //An error occurred.  
                Dts.Events.FireError(0, "SSIS variable read error:", ex.Message + "\r" + ex.StackTrace, String.Empty, 0);
                Dts.TaskResult = (int)ScriptResults.Failure;
            }  

        }

        private void ReadExecutables(Executables executables)
        {

            try
            {

                foreach (Executable pkgExecutable in executables)
                {
                    if (object.ReferenceEquals(pkgExecutable.GetType(), typeof(Microsoft.SqlServer.Dts.Runtime.TaskHost)))
                    {
                        TaskHost pkgExecTaskHost = (TaskHost)pkgExecutable;
                        if (pkgExecTaskHost.CreationName.StartsWith("SSIS.Pipeline"))
                        {
                            ProcessDataFlowTask(pkgExecTaskHost);
                        }
                    }
                    else if (object.ReferenceEquals(pkgExecutable.GetType(), typeof(Microsoft.SqlServer.Dts.Runtime.ForEachLoop)))
                    {
                        // Recurse into FELCs
                        ReadExecutables(((ForEachLoop)pkgExecutable).Executables);
                    }
                }

            }
            catch (Exception ex)
            {
                //An error occurred.  
                Dts.Events.FireError(0, "ReadExecutables error:", ex.Message + "\r" + ex.StackTrace, String.Empty, 0);
                Dts.TaskResult = (int)ScriptResults.Failure;
            }  

        }

        private void ProcessDataFlowTask(TaskHost currentDataFlowTask)
        {

            try
            {

                MainPipe currentDataFlow = (MainPipe)currentDataFlowTask.InnerObject;
                foreach (IDTSComponentMetaData100 currentComponent in currentDataFlow.ComponentMetaDataCollection)
                {
                    // Get the inputs in the component.
                    foreach (IDTSInput100 currentInput in currentComponent.InputCollection)
                        foreach (IDTSInputColumn100 currentInputColumn in currentInput.InputColumnCollection)
                           lineageId.Add(currentInputColumn.ID, currentInputColumn.Name);


                    // Get the outputs in the component.
                    foreach (IDTSOutput100 currentOutput in currentComponent.OutputCollection)
                        foreach (IDTSOutputColumn100 currentoutputColumn in currentOutput.OutputColumnCollection)
                            lineageId.Add(currentoutputColumn.ID, currentoutputColumn.Name);

                }

            }
            catch (Exception ex)
            {
                //An error occurred.  
                Dts.Events.FireError(0, "ProcessDataFlowTask error:", ex.Message + "\r" + ex.StackTrace, String.Empty, 0);
                Dts.TaskResult = (int)ScriptResults.Failure;
            }  


        }
        #region ScriptResults declaration
        /// <summary>
        /// This enum provides a convenient shorthand within the scope of this class for setting the
        /// result of the script.
        /// 
        /// This code was generated automatically.
        /// </summary>
        enum ScriptResults
        {
            Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
            Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
        };
        #endregion

    }


}
+4
source share
2 answers

" " , . , , 2 .

1
ProcessDataFlowTask lineageId.Add(...)

currentOutputColumn.Name currentInputColumn.Name


lineageId.Add(currentInputColumn.ID, currentInputColumn.Name);


strNewID = currentDataFlowTask.Name + "_" + currentInputColumn.ID.ToString();
lineageIDs.Add(strNewID, currentInputColumn.Name);

, _ _ () .


2
LineageID, (, "_" (Underscore)) Input0_ProcessInputRow script, , .

    string newColNum = "DataFlowTaskName_" + Row.ErrorColumn.Value.ToString();
    if (lineageIDs.ContainsKey(newColNum))
        Row.ErrorColumnName = lineageIDs[newColNum];


. DataFlowTaskName _ - , script, Input0_ProcessInputRow, .

. , , , .


, .

+2

,

lineageId = null;

, , strNewID.

strNewID = currentDataFlowTask.Name + "_" + currentInputColumn.ID.ToString(); lineageIDs.Add(strNewID, currentInputColumn.Name);

, ..

0

Source: https://habr.com/ru/post/1667340/


All Articles