System.Data.dll 中出现“System.IndexOutOfRangeException”类型的第一次机会异常

Posted

技术标签:

【中文标题】System.Data.dll 中出现“System.IndexOutOfRangeException”类型的第一次机会异常【英文标题】:A first chance exception of type 'System.IndexOutOfRangeException' occurred in System.Data.dll 【发布时间】:2015-03-17 09:49:15 【问题描述】:

我刚刚将此代码移动到一个新的 sub 并尝试运行它并获取异常,如 tite 中所述。

Public Sub LoadPanel(TableName As String)

    Debug.Print("LoadPanel:") 'name of module
    PushCallStack("LoadPanel") 'name of module

    Try
        Using dbConnection As New OleDbConnection(My.Settings.SMSA_databaseConnectionString)
            dbConnection.Open()
            Debug.Print("   dbConnection Success")

            Dim sqlcommand As String
            sqlcommand = "SELECT " & TableName & ".[PanelName] FROM  " & TableName & " WHERE (((" & TableName & ".[Owner])=" & CurrentClientID & ")) OR (((" & TableName & ".[Admin1])=" & CurrentClientID & ")) OR (((" & TableName & ".[Admin2])=" & CurrentClientID & ")) OR (((" & TableName & ".[Admin3])=" & CurrentClientID & ")) OR (((" & TableName & ".[Admin4])=" & CurrentClientID & "));"
            Debug.Print("   sqlcommand = " & sqlcommand)

            Dim getSomeData As New OleDbCommand(sqlcommand, dbConnection)
            With getSomeData
                .Parameters.AddWithValue("@variableName", "variableValue")
                Debug.Print("   Executing: getSomeData")
            End With
            Debug.Print("   Success: getSomeData")

            Debug.Print("   Try: DataReader")
            Using dataReader As OleDbDataReader = getSomeData.ExecuteReader
                Do While dataReader.Read
                    Dashboard_Client.ComboBox_PanelChoice.Items.Add(dataReader("PanelIP"))
                Loop
            End Using
        End Using

        PopCallStack() 'do not remove
    Catch ex As Exception
        GlobalErrHandler()
    End Try

    Debug.Print("LoadPanel End")

从调试面板:

LoadPanel:
dbConnection Success
Executing: getSomeData
Success: getSomeData
Try: DataReader
A first chance exception of type 'System.IndexOutOfRangeException' occurred in System.Data.dll

有没有办法解决此错误或进行变通以保留该功能?

谢谢。

【问题讨论】:

你能用while循环而不是do-while吗? 不幸的是,刚刚尝试并得到了同样的错误。谢谢,开发者。 您的查询中variableName 参数在哪里? \我找不到,但你添加了一个参数?? 如果 dataReader 为空,do-while 会抛出错误 【参考方案1】:

在这一行

  Dashboard_Client.ComboBox_PanelChoice.Items.Add(dataReader("PanelIP"))

您正在尝试读取名为 PanelIP 的字段,但您的查询未检索到它。 这会导致IndexOutOfRangeException,因为在内部,读取器尝试将该名称(PanelIP)转换为检索到的字段列表中的位置,并且当名称不存在时,该位置被假定为-1。当然 -1 是检索到的字段列表中的无效索引

话虽如此,让我们来看看您的查询以及如何解决它。

我希望您可以严格控制 TableName 变量,因为用户可以在该变量中传递任何内容,这可能导致称为 Sql Injection 的危险情况

要修复的是缺少的字段,并将 currentClientID 的每个字符串连接更改为适当的参数

Dim sqlcommand = "SELECT " & TableName & ".[PanelName] " & _ 
                             TableName & ".[PanelID] " & _
                 " FROM  " & TableName & _ 
                 " WHERE (" & TableName & ".[Owner])=@ownerID) " & _
                 " OR    (" & TableName & ".[Admin1])=@clientID1) " & _
                 " OR    (" & TableName & ".[Admin2])=@clientID2) " & _   
                 " OR    (" & TableName & ".[Admin3])=@clientID3) " & _ 
                 " OR    (" & TableName & ".[Admin4])=@clientID4)"

Try
    Using dbConnection As New OleDbConnection(.....)
    Using getSomeData As New OleDbCommand(sqlcommand, dbConnection)
        dbConnection.Open()
        With getSomeData
            ' In oledb you need to add a parameter for every placeholder
            ' because the parameters are not recognized by name but by position
            .Parameters.Add("@ownerID", OleDbType.Integer).Value = currentClientID
            .Parameters.Add("@clientID1", OleDbType.Integer).Value = currentClientID
            .Parameters.Add("@clientID2", OleDbType.Integer).Value = currentClientID
            .Parameters.Add("@clientID3", OleDbType.Integer).Value = currentClientID
            .Parameters.Add("@clientID4", OleDbType.Integer).Value = currentClientID
        End With
        Using dataReader As OleDbDataReader = getSomeData.ExecuteReader
            Do While dataReader.Read
                Dashboard_Client.ComboBox_PanelChoice.Items.Add(dataReader("PanelIP"))
            Loop
        End Using
    End Using
    End Using

    PopCallStack()
Catch ex As Exception
    GlobalErrHandler()
End Try

遗憾的是,无法对 TableName 进行参数化,因为参数只能用于值,不能用于字段或表名

【讨论】:

【参考方案2】:

在您尝试添加值 1 的查询广告中没有 variableName 参数。这会导致 IndexOutOfRangeException

你必须包含参数或者只是删除

.Parameters.AddWithValue("@variableName", "variableValue")

【讨论】:

对不起,但这不会导致OP提到的错误。它被简单地忽略了。但是,我同意它在问题的上下文中没有地位

以上是关于System.Data.dll 中出现“System.IndexOutOfRangeException”类型的第一次机会异常的主要内容,如果未能解决你的问题,请参考以下文章

SQL 异常未处理 - System.Data.dll 中出现“System.Data.SqlClient.SqlException”类型的未处理异常

System.Data.dll 中出现“System.InvalidOperationException”类型的第一次机会异常

System.Data.dll 中出现“System.Data.OleDb.OleDbException”类型的未处理异常附加信息:无法识别的数据库格式

错误提示:未处理的“System.NullReferenceException”类型的异常出现在 system.data.dll 中。 其他信息: 未将对象引用设置到对象的实例。

vb 上的 System.Data.dll 中发生错误 System.InvalidOperationException' [重复]

C# - INSERT INTO 语句中的语法错误(System.Data.dll 中发生“System.Data.OleDb.OleDbException”类型的未处理异常)