2

我有一个 SSIS 包,它现在因“索引超出数组范围”错误而失败。它发生在脚本组件任务中,但我在日志中看不到任何关于它失败的行的更多信息。这是我的脚本组件的文本,有人能看出这有什么问题吗?我没有更改包中的任何内容,它只是突然开始失败。

Imports System
Imports System.Data
Imports System.Math
Imports Microsoft.SqlServer.Dts.Pipeline.Wrapper
Imports Microsoft.SqlServer.Dts.Runtime.Wrapper

<Microsoft.SqlServer.Dts.Pipeline.SSISScriptComponentEntryPointAttribute> _
<CLSCompliant(False)> _
Public Class ScriptMain
    Inherits UserComponent


    ' Wrapper for web service

    'Private CurrencyInfo As RetrieveExchangeRatesOutputMessageContract

    ' wrapper for Response from web service

    Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)

        Try
            Dim ws As New CurrencyExchangeWS.CurrencyExchangeWS
            Dim inContract As New CurrencyExchangeWS.ExchangeRateInputDataContract
            Dim msg As New CurrencyExchangeWS.RetrieveExchangeRatesInputMessageContract
            Dim inContracts(1) As CurrencyExchangeWS.ExchangeRateInputDataContract
            'Dim dt As Date = Now
            'dt = dt.AddDays(-1)

            inContract.RequestAsOfDate = Now
            'inContract.RequestAsOfDate = "2011-07-18"

            ' IMPORTANT: You need to specify SourceCurrencyIdSpecified and TargetCurrencyIdSpecified or the service will assume these values are null.
            inContract.SourceCurrencyIdSpecified = True
            inContract.SourceCurrencyId = Row.CurrencyTypeId

            inContract.TargetCurrencyIdSpecified = True
            inContract.TargetCurrencyId = 47

            inContracts(0) = inContract

            msg.ExchangeRateInputCollection = inContracts

            ws.Credentials = System.Net.CredentialCache.DefaultCredentials

            Dim outMsg As CurrencyExchangeWS.RetrieveExchangeRatesOutputMessageContract = ws.RetrieveExchangeRates(msg)

            'Dim rate =outMsg.ExchangeRateInfoCollection(0).Rate
            Dim rate As Decimal = outMsg.ExchangeRateInfoCollection(0).Rate

            'Dim edate = outMsg.ExchangeRateInfoCollection(0).RequestAsOfDate

            Dim edate = outMsg.ExchangeRateInfoCollection(0).RateAsOfDate

            'Dim edate As DateTime
            'edate = outMsg.ExchangeRateInfoCollection(0).RateAsOfDate


            Row.date = edate
            Row.rate = Convert.ToDecimal(1.0 / rate)

            'Dim currency = outMsg.ExchangeRateInfoCollection(0).TargetCurrencyId


        Catch ex As Exception

            ComponentMetaData.FireError(1, ComponentMetaData.Name, ex.Message, String.Empty, 0, True)

        End Try

    End Sub
    Public Overrides Sub PreExecute()
        MyBase.PreExecute()
        '
        ' Add your code here for preprocessing or remove if not needed
        ''
    End Sub

    Public Overrides Sub PostExecute()
        MyBase.PostExecute()
        '
        ' Add your code here for postprocessing or remove if not needed
        ' You can set read/write variables here, for example:
        ' Me.Variables.MyIntVar = 100
        ''
    End Sub

    'Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)
    '
    ' Add your code here
    '
    'End Sub

End Class
4

1 回答 1

0

乍一看,最可能的罪魁祸首是outMsg.ExchangeRateInfoCollection包含零项。不幸的是,我们没有足够的信息来肯定地说。获取该附加信息的一种可能方法是在Try ... Catch块之外声明一个进度字符串变量,在代码中的每个步骤之前对其进行更新,并将其包含在FireError消息中:

Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)
    Dim progress As String

    Try
        Dim ws As New CurrencyExchangeWS.CurrencyExchangeWS
        Dim inContract As New CurrencyExchangeWS.ExchangeRateInputDataContract
        Dim msg As New CurrencyExchangeWS.RetrieveExchangeRatesInputMessageContract
        Dim inContracts(1) As CurrencyExchangeWS.ExchangeRateInputDataContract

        progress = "Setting inContract.RequestAsOfDate"
        inContract.RequestAsOfDate = Now
        progress = "Setting inContract.SourceCurrencyIdSpecified"
        inContract.SourceCurrencyIdSpecified = True

        ' etc, etc, etc.

        Dim outMsg As CurrencyExchangeWS.RetrieveExchangeRatesOutputMessageContract
        progress = "Setting outMsg"
        outMsg = ws.RetrieveExchangeRates(msg)

        progress = String.Format("Setting rate; outMsg.ExchangeRateInfoCollection.Length is {0}", outMsg.ExchangeRateInfoCollection.Length)
        ' This is likely the place where the IndexOutOfRangeException is being thrown
        Dim rate As Decimal = outMsg.ExchangeRateInfoCollection(0).Rate

        ' rest of code
    Catch ex As Exception
        ComponentMetaData.FireError(1, ComponentMetaData.Name, progress + ": " + ex.Message, String.Empty, 0, True)
    End Try
End Sub
于 2013-02-04T19:25:25.987 回答