Задача сценария служб SSIS для сбора идентификаторов линии - PullRequest
1 голос
/ 21 марта 2019

У меня есть задача сценария служб SSIS, которая собирает расширенную информацию об ошибках.

Содержимое сценария выглядит следующим образом:

/// <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<string, string> lineageIds = null;

    public void Main()
    {
        // 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<string, string>();
        lineageIds = (Dictionary<string, string>)Dts.Variables["User::lineageIds"].Value;
        Executables execs = (Executables)Dts.Variables["User::execsObj"].Value;

        ReadExecutables(execs);

        Dts.TaskResult = (int)ScriptResults.Success;
    }

    private void ReadExecutables(Executables executables)
    {
        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);
            }
        }
    }

    private void ProcessDataFlowTask(TaskHost currentDataFlowTask)
    {
        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)
                    lineageIds.Add(currentDataFlowTask.ID.ToString() + currentInputColumn.ID, currentInputColumn.Name);

            // Get the outputs in the component.
            foreach (IDTSOutput100 currentOutput in currentComponent.OutputCollection)
                foreach (IDTSOutputColumn100 currentoutputColumn in currentOutput.OutputColumnCollection)
                    lineageIds.Add(currentDataFlowTask.ID.ToString() + currentoutputColumn.ID, currentoutputColumn.Name);
        }
    }

    enum ScriptResults
    {
        Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
        Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
    };
}

Раньше он работал правильно на SQL Server 2014. Однако после обновления до SQL Server 2017 задача выдает в строке следующее сообщение об ошибке:

MainPipe currentDataFlow = (MainPipe)currentDataFlowTask.InnerObject;

Исключение типа 'System.InvalidCastException' произошло в ST_47767930511349f4b94ba74c27240570, но не было обработано в коде пользователя

Дополнительная информация: Невозможно привести объект COM типа 'System .__ ComObject' к типу интерфейса 'Microsoft.SqlServer.Dts.Pipeline.Wrapper.MainPipe'. Эта операция завершилась неудачно, поскольку вызов QueryInterface для компонента COM для интерфейса с IID '{6D3931AC-822D-414C-8F10-7447A54BA55C}' завершился ошибкой из-за следующей ошибки: такой интерфейс не поддерживается (Исключение из HRESULT: 0x80004002 (E_NOINTERFACE)) .

Кто-нибудь еще видел это после обновления до SQL Server 2017?

1 Ответ

1 голос
/ 21 марта 2019

Оказалось, что объект Com, возвращаемый currentDataFlowTask.InnerObject, был получен из более новой версии Microsoft.SqlServer.DTSPipelineWrap.

Чтобы устранить проблему, я удалил ссылку на Microsoft.SqlServer.DTSPipelineWrap и заменил ее версией 14 той же сборки.

Затем я изменил следующую строку:

MainPipe currentDataFlow = (MainPipe)currentDataFlowTask.InnerObject;

до

IDTSPipeline130 currentDataFlow = (IDTSPipeline130)currentDataFlowTask.InnerObject;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...