我刚刚将此代码移动到一个新的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
有没有办法解决此错误或进行解决以保持功能?
感谢。
答案 0 :(得分:2)
在这一行
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进行参数化,因为参数只能用于不是字段或表名的值
答案 1 :(得分:1)
您的查询广告中没有variableName
参数,您尝试添加一个值。这会导致IndexOutOfRangeException
。
您可以包含参数或只删除
.Parameters.AddWithValue("@variableName", "variableValue")