VB.net OleDbDataReader 不返回想要的值

Posted

技术标签:

【中文标题】VB.net OleDbDataReader 不返回想要的值【英文标题】:VB.net OleDbDataReader doesn't return wanted values 【发布时间】:2018-01-17 14:13:43 【问题描述】:

VB.net 中的 OleDb 只返回第一列

我不知道自己哪里出错了,连续盯着它看了 2 个小时,尝试了 150 种不同的变体。不知道错误出在哪里,导致它不返回除第一个字段之外的任何其他字段。

是的,我知道这看起来很混乱,我本来打算把 5 个读数作为一个函数,但我被这个问题弄得不知所措

Private Sub StartBtn_Click(sender As Object, e As EventArgs) Handles StartBtn.Click
    Dim Numbers As New List(Of Integer)
    For X As Integer = 1 To 15
        Dim Num As Integer = RandomNum()
        Numbers.Add(Num)
    Next

    Dim temp_QuestionSet As New List(Of Question)

    provider = "Provider=Microsoft.ACE.OLEDB.12.0;"
    dataFile = "Data Source=C:\course work\dttmq.accdb"
    connString = provider & dataFile
    Try
        Connection.ConnectionString = connString
        Connection.Open()
    Catch ex As Exception
        System.Console.Beep()
        MsgBox("Error")
    End Try

    For Each Number In Numbers
        Dim _question As New Question

        _question.ID = Number

        Using Connection
            Dim command As New OleDbCommand("SELECT Question FROM final WHERE QuestionID = " & Number.ToString, Connection)
            Try
                Dim reader As OleDbDataReader = command.ExecuteReader()
                While reader.Read()
                    _question.Q = reader(0).ToString()
                End While
                reader.Close()
            Catch ex As Exception
            End Try
        End Using

        Using Connection
            Dim command As New OleDbCommand("SELECT (Answer1) FROM final WHERE QuestionID = " & Number.ToString, Connection)
            Try
                Dim reader As OleDbDataReader = command.ExecuteReader()
                While reader.Read()
                    _question.A = reader(0).ToString()
                End While
                reader.Close()
            Catch ex As Exception
            End Try
        End Using

        Using Connection
            Dim command As New OleDbCommand("SELECT Answer2 FROM final WHERE QuestionID = " & Number.ToString, Connection)
            Try
                Dim reader As OleDbDataReader = command.ExecuteReader()
                While reader.Read()
                    _question.B = reader(0).ToString()
                End While
                reader.Close()
            Catch ex As Exception
            End Try
        End Using

        Using Connection
            Dim command As New OleDbCommand("SELECT Answer3 FROM final WHERE QuestionID = " & Number.ToString, Connection)
            Try
                Dim reader As OleDbDataReader = command.ExecuteReader()
                While reader.Read()
                    _question.C = reader(0).ToString()
                End While
                reader.Close()
            Catch ex As Exception
            End Try
        End Using

        Using Connection
            Dim command As New OleDbCommand("SELECT Answer4 FROM final WHERE QuestionID = " & Number.ToString, Connection)
            Try
                Dim reader As OleDbDataReader = command.ExecuteReader()
                While reader.Read()
                    _question.D = reader(0).ToString()
                End While
                reader.Close()
            Catch ex As Exception
            End Try
        End Using

        Using Connection
            Dim command As New OleDbCommand("SELECT CorrectAnswer FROM final WHERE QuestionID = " & Number.ToString, Connection)
            Try
                Dim reader As OleDbDataReader = command.ExecuteReader()
                While reader.Read()
                    _question.Z = reader(0).ToString()
                End While
                reader.Close()
            Catch ex As Exception
            End Try
        End Using
        temp_QuestionSet.Add(_question)
    Next
End Sub

【问题讨论】:

阅读***.com/help/mcve,然后编辑您的问题。 “只返回第一列”是什么意思?您首先只选择一列...另外,我认为您不了解Using Connection 在做什么,可能想更深入地了解该语句的作用以及应该如何使用它...因为现在,你基本上是在处理它 6 次,巧合地关闭它 您的SELECT 查询只检索到一列,而您正在通过reader(0).ToString() 阅读它,这就是为什么您总是得到第一列,我在这里看不到任何问题! SELECT Question FROM 目前您正在对Numbers 中的每个数字和每列分别运行查询,这意味着 6*15=90 个查询 (!)。虽然它可以在一个查询中完成,例如:"SELECT Question, Answer1, Answer2, Answer3, Answer4, CorrectAnswer FROM final WHERE QuestionID IN (" & String.Join(",", Numbers) & ");" - 另外我猜想使用RandomNum()-方法可能会在 for 循环内生成重复的数字。 【参考方案1】:

循环外有一个连接,循环内有多个命令。虽然这是朝着正确的方向倾斜,但每个命令都包含在针对连接对象的 Using 块中。这意味着您在第一次通过循环时在第一个命令结束时处置连接,从而使连接无法使用。

当我在这里时,您还应该查看参数化查询。

将所有这些以及其他一些更改放在一起,您最终会得到:

Dim temp_QuestionSet As New List(Of Question)
Private Sub StartBtn_Click(sender As Object, e As EventArgs) Handles StartBtn.Click
    temp_QuestionSet.Clear()
    Dim QuestionSql As String = "SELECT Question, Answer1, Answer2, Answer3, Answer4, CorrectAnswer FROM final WHERE QuestionID = ?"

    provider = "Provider=Microsoft.ACE.OLEDB.12.0;"
    dataFile = "Data Source=C:\course work\dttmq.accdb"
    connString = provider & dataFile

    Using Connection As New OleDbConnection(connString), _
          command As New OleDbCommand(QuestionSql, Connection)

        command.Parameters.Add("ID", OleDbType.Integer)
        Connection.Open()

        For Each Number In Enumerable.Range(0,15).Select(Function(i) RandomNum())

            command.Parameters("ID").Value = Number
            Try
                Dim reader As OleDbDataReader = command.ExecuteReader()
                While reader.Read()
                    temp_QuestionSet.Add(New Question With 
                    .ID = Number,
                    .Q = reader("Question").ToString(),
                    .A = reader("Answer1").ToString(),
                    .B = reader("Answer2").ToString(),
                    .C = reader("Answer3").ToString(),
                    .D = reader("Answer4").ToString(),
                    .Z = reader("CorrectAnswer").ToString())
                End While
                reader.Close()
            Catch ex As Exception
               MsgBox("Error: " & ex.Message)
               Console.Beep()
            End Try
        Next

    End Using
End Sub

我还会考虑将其归结为一次访问您的数据库以一次性加载所有问题,然后重新排列结果。我提供的代码应该可以很容易地朝着这个方向前进,您只需更改 SQL 命令即可完成此操作。

【讨论】:

以上是关于VB.net OleDbDataReader 不返回想要的值的主要内容,如果未能解决你的问题,请参考以下文章

访问 OleDbDataReader 项目时出现 IndexOutOfRange 错误

OleDbDatareader 十进制问题

OleDbDataReader快速数据读取方式

OleDbDataReader 如何读取数字类型?

如何防止 OleDbDataReader.ExecuteReader 自动附加整数以复制列值

OleDbDataReader 对象无法读取文件