【问题标题】:SSIS upgrade from 2008R2 to 2017 - script task fails when connecting to OLEDB data sourceSSIS 从 2008R2 升级到 2017 - 连接到 OLEDB 数据源时脚本任务失败
【发布时间】:2024-04-19 18:15:01
【问题描述】:

我正在将数据仓库从 SQL Server 2008R2 升级到 2017。升级后,每个脚本任务在尝试连接到日志数据库时都会抛出相同的错误。

任务通过 OLEDB 连接管理器连接到数据库,然后将一些元数据写入日志表。建立初始连接失败。我希望这是一个相当简单的调用错误,但我是一个 SQL 人,而不是 VB 人,我没有看到这个问题。

我发现了这个问题,Missing library to reference OLEDB connection types,但脚本没有调用 AcquireConnection() 方法,所以我认为它不适用。或者如果是,我不知道如何。

这是通过故障点的代码。

Imports System
Imports System.Data
Imports System.Math
Imports Microsoft.SqlServer.Dts.Runtime
Imports System.Data.OleDb
Imports System.Collections
Imports Microsoft.SqlServer.Dts.Runtime.Wrapper

<Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute> _
<System.CLSCompliantAttribute(False)> _
Partial Public Class ScriptMain
  Inherits Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase

  Enum ScriptResults
    Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success
    Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
  End Enum

    Public Sub Main()
        Dim fireAgain As Boolean
        Dim pkgExecVar As Variables
        Dim cm As ConnectionManager
    Dim cmParam As IDTSConnectionManagerDatabaseParameters100
    Dim conn As OleDb.OleDbConnection
    Dim cmd As OleDbCommand = New OleDbCommand()

    pkgExecVar = Nothing
    cm = Dts.Connections("Configuration_Metadata_Logging")
    cmParam = CType(cm.InnerObject, IDTSConnectionManagerDatabaseParameters100)
    conn = CType(cmParam.GetConnectionForSchema(), OleDb.OleDbConnection)

当我单步执行代码时,倒数第二行抛出异常。

cmParam = CType(cm.InnerObject, IDTSConnectionManagerDatabaseParameters100)

System.InvalidCastException H结果=0x80004002 消息=无法将“System.__ComObject”类型的 COM 对象转换为接口类型“Microsoft.SqlServer.Dts.Runtime.Wrapper.IDTSConnectionManagerDatabaseParameters100”。此操作失败,因为 IID 为“{624862CB-55F9-4A92-965F-62BC4935296A}”的接口的 COM 组件上的 QueryInterface 调用因以下错误而失败:不支持此类接口(HRESULT 异常:0x80004002 (E_NOINTERFACE)) .

如果还有什么我可以添加到问题中来帮助的,请告诉我。

编辑:OLEDB 连接管理器正在使用 SQLNCLI11.1。包的其他组件(执行 SQL 和数据流任务)能够成功连接。

编辑二:为了使其更易于搜索,这是包抛出的初始错误,在向脚本任务添加断点并单步执行之前。

调用的目标已抛出异常。

在 System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) 在 System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(对象 obj,对象 [] 参数,对象 [] 参数) 在 System.Reflection.RuntimeMethodInfo.Invoke(Object obj,BindingFlags invokeAttr,Binder binder,Object[] 参数,CultureInfo 文化) 在 System.RuntimeType.InvokeMember(字符串名称、BindingFlags bindingFlags、Binder binder、Object 目标、Object[] providedArgs、ParameterModifier[] 修饰符、CultureInfo 文化、String[] namedParams) 在 Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTATaskScriptingEngine.ExecuteScript()

【问题讨论】:

  • 查看您的 OLEDB 连接并确保它为数据库所在的 SQL Server 版本使用正确的提供程序。也许它会自动将提供程序升级到比您更新的版本。
  • @TabAlleman,OLEDB 连接管理器正在使用 SQLNCLI11.1。包的其他组件(执行 SQL 和数据流任务)能够成功连接,我也将其添加到问题中。好主意,不过,我以前没有验证过。

标签: sql-server vb.net ssis sql-server-2017 ssis-2017


【解决方案1】:

更新。我找到了该代码的来源,它是 Matt Mason 的博客文章,名为 Accessing OLEDB Connection Managers in a Script。它仍然没有记录,并且可能在 SQL 2008 和 2017 之间的某个时间被破坏。

此处记录了支持的方法:Connecting to Data Sources in the Script Task

在脚本任务中获取 System.Data.OleDbConnection 的唯一方法是

1) 使用 ADO.NET 连接管理器并将其配置为使用 ADO.NET Provider for OleDb,如下所示:

 Dim cm As ConnectionManager = Dts.Connections("Configuration_Metadata_Logging_adonet_oledb")
 Dim conn As OleDb.OleDbConnection = CType(cm.AcquireConnection(Nothing), OleDb.OleDbConnection)

2) 使用 OleDb Connection Mamanger 并使用其 ConnectionString 创建一个新的 OleDbConnection(您还负责在脚本任务中关闭它)。像这样:

Dim cm2 As ConnectionManager = Dts.Connections("Configuration_Metadata_Logging_oledb")
Using conn2 As New OleDb.OleDbConnection(cm2.ConnectionString)
    conn2.Open()

End Using

【讨论】:

  • 我不知道 VB,但连接管理器是另一回事。这绝对是一个 OLEDB 连接。不过,你提出了一个很好的观点。这些包已经在 08R2 上运行多年,但我还没有对当前代码和转换前的代码进行并行处理。我想知道升级是否让我完全失去了一些东西。我现在是移动设备,但当我回到电脑前,我会看看这种可能性。
  • 我找到了该模式的来源并更新了答案。
  • 感谢您关注该博文。有点像吸烟枪。不方便的是,事实证明,当它们在新服务器上运行时,连接仍然有效,但在我的本地机器上却不行。所以我仍然认为让它“正确”很重要,但这样做的紧迫性已经消失了。不过,这仍然是一个可靠的答案。