如何修复Biml内置SSIS脚本任务的失败任务:不支持此类界面

时间:2019-04-03 18:28:11

标签: c# ssis biml

我一直在测试通过Biml for SSIS包创建脚本任务。 我希望能够在本地成功执行/测试软件包。

我无法从本地开发环境中执行项目的程序包,因为它们全部出错,且以下相同。

问题: Error: 0x0 at ScriptTask 1, Script Task : Unable to cast COM object of type 'System.__ComObject' to interface type 'Microsoft.SqlServer.Dts.Runtime.Wrapper.IDTSVariables100'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{2CD38B23-6C17-4025-A8B6-D2E497DD1DDC}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)). at Microsoft.SqlServer.Dts.Runtime.Variables.get_Item(Object index) at ScriptMain.Main() Error: 0x6 at ScriptTask 1: The script returned a failure result. Task failed: ScriptTask 1

在将项目从Visual Studio部署到该服务器上的SSIS目录(SSISDB)(SQL Server 2016)之后,我能够从另一台服务器成功执行这些程序包。

我对AssemblyInfo和ScriptMain使用了以下引用:

<Script ProjectCoreName="ST_232fecafb70a4e8a904cc21f8870eed0" Name="ScriptTask 1">
    <ScriptTaskProject>
        <ScriptTaskProject ProjectCoreName="ST_c41ad4bf47544c49ad46f4440163feae" Name="TaskScriptProject1">
            <AssemblyReferences>
                <AssemblyReference AssemblyPath="Microsoft.SqlServer.ManagedDTS.dll" />
                <AssemblyReference AssemblyPath="Microsoft.SqlServer.ScriptTask.dll" />
                <AssemblyReference AssemblyPath="System.dll" />
                <AssemblyReference AssemblyPath="System.AddIn.dll" />
                <AssemblyReference AssemblyPath="System.Data.dll" />
                <AssemblyReference AssemblyPath="System.Windows.Forms.dll" />
                <AssemblyReference AssemblyPath="System.Xml.dll" />
            </AssemblyReferences>
            <Files>
                <File Path="AssemblyInfo.cs">
                    using System.Reflection;
                    using System.Runtime.CompilerServices;

                    //
                    // General Information about an assembly is controlled through the following
                    // set of attributes. Change these attribute values to modify the information
                    // associated with an assembly.
                    //
                    [assembly: AssemblyTitle("ST_c41ad4bf47544c49ad46f4440163feae.csproj")]
                    [assembly: AssemblyDescription("")]
                    [assembly: AssemblyConfiguration("")]
                    [assembly: AssemblyCompany("Varigence")]
                    [assembly: AssemblyProduct("ST_c41ad4bf47544c49ad46f4440163feae.csproj")]
                    [assembly: AssemblyCopyright("Copyright @ Varigence 2013")]
                    [assembly: AssemblyTrademark("")]
                    [assembly: AssemblyCulture("")]
                    //
                    // Version information for an assembly consists of the following four values:
                    //
                    //      Major Version
                    //      Minor Version
                    //      Build Number
                    //      Revision
                    //
                    // You can specify all the values or you can default the Revision and Build Numbers
                    // by using the '*' as shown below:

                    [assembly: AssemblyVersion("1.0.*")]
                </File>
                <File Path="ScriptMain.cs">
                    using System;
                    using System.Data;
                    using Microsoft.SqlServer.Dts.Runtime;
                    using System.Windows.Forms;

                    // if SSIS2012, use the following line:
                    [Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]

                    // if earlier version, use the next line instead of the above line:
                    // [System.AddIn.AddIn("ScriptMain", Version = "1.0", Publisher = "", Description = "")]
                    public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
                    {
                        enum ScriptResults
                        {
                            Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
                            Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
                        };

                        public void Main()
                        {
                            try
                            {
                                int totalInsertedRowsToDestination = (int)Dts.Variables["User::TotalInsertedRowsToDestination"].Value;
                                int rowCountNew = (int)Dts.Variables["User::RowCountNew"].Value;
                                int totalUpdatedRowsToDestination = (int)Dts.Variables["User::TotalUpdatedRowsToDestination"].Value;
                                int rowCountChanged = (int)Dts.Variables["User::RowCountChanged"].Value;
                                int totalUnChangedRowsToDestination = (int)Dts.Variables["User::TotalUnChangedRowsToDestination"].Value;
                                int rowCountUnchanged = (int)Dts.Variables["User::RowCountUnchanged"].Value;

                                totalInsertedRowsToDestination += rowCountNew;
                                totalUpdatedRowsToDestination += rowCountChanged;
                                totalUnChangedRowsToDestination += rowCountUnchanged;

                                Dts.Variables["User::TotalInsertedRowsToDestination"].Value = totalInsertedRowsToDestination;
                                Dts.Variables["User::TotalUpdatedRowsToDestination"].Value = totalUpdatedRowsToDestination;
                                Dts.Variables["User::TotalUnChangedRowsToDestination"].Value = totalUnChangedRowsToDestination;

                                Dts.TaskResult = (int)ScriptResults.Success;
                            }
                            catch (Exception ex)
                            {
                                Dts.Events.FireError(0, "Script Task ", ex.Message + "\r" + ex.StackTrace, String.Empty, 0);
                                Dts.TaskResult = (int)ScriptResults.Failure;
                            }
                        }                                   
                    }
                </File>
            </Files>
            <ReadOnlyVariables>
                <Variable Namespace="User" DataType="Int32" VariableName="RowCountNew" />
                <Variable Namespace="User" DataType="Int32" VariableName="RowCountChanged" />
                <Variable Namespace="User" DataType="Int32" VariableName="RowCountUnchanged" />
            </ReadOnlyVariables>
            <ReadWriteVariables>
                <Variable Namespace="User" DataType="Int32" VariableName="TotalInsertedRowsToDestination" />
                <Variable Namespace="User" DataType="Int32" VariableName="TotalUpdatedRowsToDestination" />
                <Variable Namespace="User" DataType="Int32" VariableName="TotalUnChangedRowsToDestination" />
            </ReadWriteVariables>
        </ScriptTaskProject>
    </ScriptTaskProject>
    <PrecedenceConstraints>
        <Inputs>
          <Input OutputPathName="SQL Update <#=dstTableName#>.Output" />
        </Inputs>
    </PrecedenceConstraints>
</Script>

我希望输出为:SSIS package finished: Success,脚本任务中没有错误。

我的环境:

  • Windows 10 Enterprise 6.3 x64
  • Microsoft Visual Studio 2015 Shell (integrated): 14.0.23107.0
  • Microsoft .NET Framework: 4.7.03056
  • BimlExpress: 1.0
  • SQL Server Data Tools: 14.0.61705.170
  • SQL Server 2016 (SP1-GDR): 13.0.4224.16(x64)

2 个答案:

答案 0 :(得分:3)

我在多个不同的环境/机器上本地复制了该错误,并确定了解决方法。

解决方案:将SSIS项目的 TargetServerVersion SQL Server 2014更改为SQL Server 2016。 运行程序包后,结果消息为SSIS package finished: Success

原因:

这些环境中缺少与IDTSVa​​riables100接口相关的SQL Server 2014的TargetServerVersion所需的组件。该接口与SQL Server .NET SDK 2017 2016有关。 https://www.postgresql.org/docs/9.0/datatype-binary.html

关于TargetServerVersion和ProjectVersion,Andy Leonard在他的博客文章中解释说,
  

” TargetServerVersion属性可用于使用最新工具维护SSIS项目的当前生产版本,只要当前生产版本为SSIS 2012+。并且TargetServerVersion属性可以更新为最新版本只需更改下拉菜单中的值即可使用该版本。   https://docs.microsoft.com/en-us/dotnet/api/microsoft.sqlserver.dts.runtime.wrapper.idtsvariables100?view=sqlserver-2017

<ProductVersion>14.0.600.250</ProductVersion>

下面的 SSDT其他参考部分中有更多想法。

操作方法:

  1. 在Visual Studio中右键单击SSIS项目 [MySsisProject(SQL Server 2014)] ,然后选择“属性”。

https://andyleonard.blog/2018/08/a-tale-of-two-properties-ssis-projectversion-and-targetserverversion/

  1. 在新打开的“属性页”中,展开“配置属性”组,然后选择“常规”。然后选择适当的TargetServerVersion(在我的情况下为SQL Server 2016)

select Properties of SSIS project

  1. 阅读警告,提及扩展可能存在的问题,并确定是否要继续。

select TargetServerVersion

现在,SSIS项目的项目名称MySsisProject (SQL Server 2016)后面的括号中带有SQL Server 2016。这样可以解决问题。 接下来,在本地执行软件包以验证软件包是否成功完成。

经过测试的环境/机器:

  1. 环境:

    • Windows 10 Enterprise 6.3 x64
    • Microsoft Visual Studio 2015 Shell (integrated): 14.0.23107.0
    • Microsoft .NET Framework: 4.7.03056
    • BimlExpress: 1.0
    • SQL Server Data Tools: 14.0.61705.170
    • SQL Server 2016 (SP1-GDR): 13.0.4224.16(x64)
  2. 环境:

    • Windows 10 Enterprise 6.3 x64
    • Microsoft Visual Studio Enterprise 2017: 15.9.8
    • Microsoft .NET Framework: 4.7.03056
    • BimlExpress: 1.0
    • SQL Server Data Tools: 15.1.61902.21100
    • SQL Server 2016 (SP1-GDR): 13.0.4224.16(x64)
  3. 环境:

    • Windows Server 2012 R2 Datacenter 6.3 x64
    • Microsoft Visual Studio Professional 2015: 14.0.25431.01 Update 3
    • Microsoft .NET Framework: 4.7.02053
    • BimlExpress: 1.0
    • SQL Server Data Tools: 14.0.61705.170
    • SQL Server 2016 (SP1): 13.0.4001.0(x64)

SSDT的其他参考(SQL Server数据工具):

答案 1 :(得分:0)

在我们决定删除不同的路径后,我们也遇到了一些环境问题。 因为有些人在 GAC 中有一个 dll,而其他人只有在 Visual Studio PublicAssemblies 目录中

我们仍然想删除路径,但仍然需要提供有关目标版本的提示。

我们现在在 Biml 中修复它,执行程序集引用,如下所示:

<AssemblyReference AssemblyPath="Microsoft.SqlServer.DTSRuntimeWrap, Version=14.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=x86, Custom=null" />

并使其更易于用于其他 dll,如下所示:

<# int MajorSQLVersion  = 13; #>
<AssemblyReference AssemblyPath="Microsoft.SqlServer.DTSRuntimeWrap, Version=<#= MajorSQLVersion.ToString() #>.0.0.0" />