reader 关闭时读取无效尝试错误
Invalid attempt to read when reader is closed Error
我被这个问题难住了,我的数据库是本地主机,我对所有其他形式都没有问题,但是在这里,当我单击更新按钮时,我收到这个错误,这非常令人沮丧,因为我非常确定SQL 连接应该打开!我的按钮代码已给出。
Error: 'Invalid attempt to read when reader is closed'
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'
您的问题可能只是一个 copy/paste 错误。似乎在为最后一个 SELECT 命令执行 reader 之前,您关闭了连接。 (正如您在前两个 UPDATE 命令中所做的那样)这实际上是错误消息的原因。
但是你的代码中还有其他问题。
第一。您应该使用 ExecuteNonQuery 发送更新。当您想通过 SELECT 查询从数据库中读回某些内容时,将使用 ExecuteReader。它也适用于 UPDATE/INSERT/DELETE 等,但不需要为阅读创建的基础设施,因此是无用的资源消耗。
第二。您可以使用单个命令文本发送两个(或更多)命令。只需用分号分隔两个命令并通过 ExecuteNonQuery
执行命令文本
第三。您应该始终使用参数化查询来避免 Sql Injection 和解析您的值时出现问题。例如,小数包含小数分隔符,在您的语言环境中通过特定符号表示,但在其他语言环境中则不同,因此您的查询停止工作。 (同样的问题也发生在包含单引号的普通字符串中)。参数方法将消除这两个问题。
终于。所有一次性对象,如 Connections、Commands 和 Readers,都应在您用完后丢弃。 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
我被这个问题难住了,我的数据库是本地主机,我对所有其他形式都没有问题,但是在这里,当我单击更新按钮时,我收到这个错误,这非常令人沮丧,因为我非常确定SQL 连接应该打开!我的按钮代码已给出。
Error: 'Invalid attempt to read when reader is closed'
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'
您的问题可能只是一个 copy/paste 错误。似乎在为最后一个 SELECT 命令执行 reader 之前,您关闭了连接。 (正如您在前两个 UPDATE 命令中所做的那样)这实际上是错误消息的原因。
但是你的代码中还有其他问题。
第一。您应该使用 ExecuteNonQuery 发送更新。当您想通过 SELECT 查询从数据库中读回某些内容时,将使用 ExecuteReader。它也适用于 UPDATE/INSERT/DELETE 等,但不需要为阅读创建的基础设施,因此是无用的资源消耗。
第二。您可以使用单个命令文本发送两个(或更多)命令。只需用分号分隔两个命令并通过 ExecuteNonQuery
执行命令文本第三。您应该始终使用参数化查询来避免 Sql Injection 和解析您的值时出现问题。例如,小数包含小数分隔符,在您的语言环境中通过特定符号表示,但在其他语言环境中则不同,因此您的查询停止工作。 (同样的问题也发生在包含单引号的普通字符串中)。参数方法将消除这两个问题。
终于。所有一次性对象,如 Connections、Commands 和 Readers,都应在您用完后丢弃。 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