【问题标题】:SSIS script task to collect lineage IDs用于收集沿袭 ID 的 SSIS 脚本任务
【发布时间】:2019-08-12 09:54:03
【问题描述】:

我有一个收集扩展错误信息的 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;

在 ST_47767930511349f4b94ba74c27240570 中发生了“System.InvalidCastException”类型的异常,但未在用户代码中处理

附加信息:无法将“System.__ComObject”类型的 COM 对象转换为接口类型“Microsoft.SqlServer.Dts.Pipeline.Wrapper.MainPipe”。此操作失败,因为 IID 为“{6D3931AC-822D-414C-8F10-7447A54BA55C}”的接口的 COM 组件上的 QueryInterface 调用因以下错误而失败:不支持此类接口(来自 HRESULT 的异常:0x80004002 (E_NOINTERFACE)) .

自从升级到 SQL Server 2017 后,还有其他人看到过这种情况吗?

【问题讨论】:

  • 我们在从低级 SQL 迁移到高级 SQL 时遇到了很多错误。您是否尝试过打开包,打开脚本任务,重新构建它,然后再次关闭它? (有时只需要重新编译),修复了我们升级时的很多错误
  • 我们在 SQL VS 版本之间升级脚本时遇到大量问题。太多了,我们开始从我们的包中删除它们。
  • @Brad 所有的包都被打开和关闭了。
  • 并且每个脚本任务本身都被打开和关闭了?只打开包是不行的,你需要打开每个单独的脚本任务。
  • 为了安全起见,打开脚本任务,构建它,关闭它并保存包。

标签: c# sql-server ssis etl script-task


【解决方案1】:

原来 currentDataFlowTask.InnerObject 返回的 Com 对象来自更新版本的 Microsoft.SqlServer.DTSPipelineWrap。

为了解决这个问题,我删除了对 Microsoft.SqlServer.DTSPipelineWrap 的引用并替换为同一程序集的版本 14。

然后我更改了以下行:

MainPipe currentDataFlow = (MainPipe)currentDataFlowTask.InnerObject;

IDTSPipeline130 currentDataFlow = (IDTSPipeline130)currentDataFlowTask.InnerObject;

【讨论】:

  • SSIS 中的 C# 脚本...像海象一样优雅。但是请投赞成票!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-03
  • 2011-03-21
  • 1970-01-01
  • 2018-05-05
  • 2014-09-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多