读取器关闭时无效读取错误

时间:2015-01-25 17:46:53

标签: mysql vb.net

我很难解决这个问题,我的数据库是本地主机和其他所有形式我没有问题但是在这里,当我点击更新按钮时,我得到这个错误,这非常令人沮丧,因为我非常确定SQL连接应该是开放的!我给出了按钮的代码。

  

错误:'读取器关闭时读取的次数无效'

Private Sub UpdateButton_Click(sender As Object, e As EventArgs) Handles UpdateButton.Click

    MysqlConn = New MySqlConnection
    MysqlConn.ConnectionString = "server=localhost;userid=root;password=alpine;database=database1"
    Dim Reader As MySqlDataReader

    Dim vals(2, 2) As Decimal
    vals(0, 2) = Convert.ToDecimal(Cbudget.Text.ToString - OutBox.Text.ToString + InBox.Text.ToString)
    vals(1, 0) = Convert.ToDecimal(Newfigbox.Text.ToString)
    vals(2, 0) = Convert.ToDecimal(OutBox.Text.ToString - InBox.Text.ToString)
    vals(1, 1) = Convert.ToDecimal(FigureBox.Text.ToString + Newfigbox.Text.ToString)

    Try
        MysqlConn.Open()
        Dim Query As String
        Query = "UPDATE accounts SET Current_Budget='" & vals(1, 0) & "';"
        Command = New MySqlCommand(Query, MysqlConn)
        Reader = Command.ExecuteReader
        MysqlConn.Close()
    Catch ex As MySqlException
        MessageBox.Show(ex.Message)
        MysqlConn.Close()
    End Try

    Try
        MysqlConn.Open()
        Dim Query As String
        Query = "UPDATE stocktable, clientdetails SET stocktable.Quantity='" & vals(1, 1) & "', clientdetails.Balance='" & vals(2, 0) & "' WHERE 'stocktable.Type_Of_Metal' ='" & ComboBox1.Text & "' AND 'clientdetails.Name' ='" & ClientBox.Text & "';"
        Command = New MySqlCommand(Query, MysqlConn)
        Reader = Command.ExecuteReader
        MysqlConn.Close()
    Catch ex As MySqlException
        MessageBox.Show(ex.Message)
        MysqlConn.Close()
    End Try
    Cbudget.Text = Nothing
    Try
        MysqlConn.Open()
        Dim Query As String
        Query = "SELECT Current_Budget FROM accounts"
        Command = New MySqlCommand(Query, MysqlConn)
        Reader = Command.ExecuteReader
        MysqlConn.Close()
        While Reader.Read
            vals(0, 1) = Reader.GetDecimal("Current_Budget")
            Cbudget.Text = vals(0, 1)
        End While
        MysqlConn.Close()
    Catch ex As MySqlException
        MessageBox.Show(ex.Message)
        MysqlConn.Close()
    End Try

End Sub'

1 个答案:

答案 0 :(得分:2)

可能你的问题只是复制/粘贴错误。似乎在执行最后一个SELECT命令的阅读器之前,您关闭了连接。 (正如您在前两个UPDATE命令中所做的那样)这实际上是您的错误消息的原因 但是你的代码中还有其他一些问题。

<强>第一即可。你应该使用ExecuteNonQuery发送你的UPDATE。当您想通过SELECT查询从数据库中读回内容时,使用ExecuteReader。它也适用于UPDATE / INSERT / DELETE等,但不需要为阅读而创建的基础设施,因此无用的资源消耗。

<强>第二即可。您可以使用单个commandtext发送两个(或更多)命令。只需用分号分隔这两个命令,然后通过ExecuteNonQuery

执行commandtext

<强>第三即可。您应始终使用参数化查询来避免Sql Injection以及解析值时出现问题。例如,十进制包含您的语言环境中通过特定符号表示的小数分隔符,但在其他语言环境中则不同,因此您的查询将停止工作。 (同样的问题也发生在包含单引号的普通字符串中)。参数方法将消除这两个问题。

<强>最后即可。所有一次性对象(如连接,命令和读取器)都应在完成使用后进行处理。 Using Statement确保了这种正确的行为(如果您想知道连接的关闭,End Using也会关闭连接)

Dim vals(2, 2) As Decimal
vals(0, 2) = Convert.ToDecimal(Cbudget.Text.ToString - OutBox.Text.ToString + InBox.Text.ToString)
vals(1, 0) = Convert.ToDecimal(Newfigbox.Text.ToString)
vals(2, 0) = Convert.ToDecimal(OutBox.Text.ToString - InBox.Text.ToString)
vals(1, 1) = Convert.ToDecimal(FigureBox.Text.ToString + Newfigbox.Text.ToString)

Query = "UPDATE accounts SET Current_Budget=@budget; " & _
        "UPDATE stocktable, clientdetails " & _
        "SET stocktable.Quantity=@qty, " & _
        "clientdetails.Balance=@bal " & _ 
        "WHERE `stocktable`.`Type_Of_Metal` = @type " & _
        "AND `clientdetails`.`Name` = @client;"
Try
    Using MysqlConn = New MySqlConnection(...constring here...)
    Using Command = New MySqlCommand(Query, MysqlConn)
        command.Parameters.AddWithValue("@budget", vals(1, 0))
        command.Parameters.AddWithValue("@qty", vals(1, 1))
        command.Parameters.AddWithValue("@bal", vals(2, 0))
        command.Parameters.AddWithValue("@type", ComboBox1.Text)
        command.Parameters.AddWithValue("@client", ClientBox.Text)
        command.ExecuteNonQuery()

        Command.CommandText = "SELECT Current_Budget FROM accounts"
        Command.Parameters.Clear()        
        Using Reader = Command.ExecuteReader()
            While Reader.Read
                vals(0, 1) = Reader.GetDecimal("Current_Budget")
                Cbudget.Text = vals(0, 1)
            End While
        End Using
    End Using
Catch ex As MySqlException
    MessageBox.Show(ex.Message)
End Try