尝试插入、更新或删除时出错:已经有一个打开的 DataReader 与此命令关联,必须先关闭

Posted

技术标签:

【中文标题】尝试插入、更新或删除时出错:已经有一个打开的 DataReader 与此命令关联,必须先关闭【英文标题】:Error when trying to Insert, Update or Delete: There is already an open DataReader associated with this Command which must be closed first 【发布时间】:2017-02-16 09:56:14 【问题描述】:
Imports mysql.Data.MySqlClient

Public Class manageAdminAccounts
    Dim MysqlConn As MySqlConnection
    Dim COMMAND As MySqlCommand
    Dim dbDataSet As New DataTable
    Dim SDA As New MySqlDataAdapter

    Private Sub btnBack_Click(sender As Object, e As EventArgs) Handles btnBack.Click
        manageAccounts.Show()
        Me.Hide()
    End Sub

    Private Sub btnInsert_Click(sender As Object, e As EventArgs) Handles btnInsert.Click

        MysqlConn = New MySqlConnection
        MysqlConn.ConnectionString = "Server=localhost;Uid=root;Pwd=;Database=ilycean;"
        Dim READER As MySqlDataReader

        Try
            MysqlConn.Open()
            Dim Query As String
            Query = "insert into ilycean.users(name,email,password) values ('" & txtName.Text & "', '" & txtEmail.Text & "', '" & txtPassword.Text & "')"
            COMMAND = New MySqlCommand(Query, MysqlConn)
            READER = COMMAND.ExecuteReader

            MessageBox.Show("Data inserted")
            txtID.ResetText()
            txtName.ResetText()
            txtEmail.ResetText()
            txtPassword.ResetText()
            txtPassword.ResetText()
            RefreshData()
            READER.Close()
            MysqlConn.Close()
        Catch ex As MySqlException
            MessageBox.Show(ex.Message)
        Finally
            MysqlConn.Dispose()
            COMMAND.Dispose()
        End Try

    End Sub

    Private Sub btnEdit_Click(sender As Object, e As EventArgs) Handles btnEdit.Click
        MysqlConn = New MySqlConnection
        MysqlConn.ConnectionString = "Server=localhost;Uid=root;Pwd=;Database=ilycean;"
        Dim READER As MySqlDataReader

        Try
            MysqlConn.Open()
            Dim Query As String
            Query = "update ilycean.users Set name='" & txtName.Text & "', email='" & txtEmail.Text & "', password='" & txtPassword.Text & "' where id='" & txtID.Text & "' "
            COMMAND = New MySqlCommand(Query, MysqlConn)
            READER = COMMAND.ExecuteReader

            MessageBox.Show("Data Updated")
            txtID.ResetText()
            txtName.ResetText()
            txtEmail.ResetText()
            txtPassword.ResetText()
            txtPassword.ResetText()
            RefreshData()

            READER.Close()
            MysqlConn.Close()
        Catch ex As MySqlException
            MessageBox.Show(ex.Message)
        Finally
            MysqlConn.Dispose()
            COMMAND.Dispose()
        End Try

    End Sub

    Private Sub btnDelete_Click(sender As Object, e As EventArgs) Handles btnDelete.Click
        MysqlConn = New MySqlConnection
        MysqlConn.ConnectionString = "Server=localhost;Uid=root;Pwd=;Database=ilycean;"
        Dim READER As MySqlDataReader

        Try
            MysqlConn.Open()
            Dim Query As String
            Query = "Delete from ilycean.users where id='" & txtID.Text & "'"
            COMMAND = New MySqlCommand(Query, MysqlConn)
            READER = COMMAND.ExecuteReader

            MessageBox.Show("Data Deleted")
            txtID.ResetText()
            txtName.ResetText()
            txtEmail.ResetText()
            txtPassword.ResetText()
            txtPassword.ResetText()
            RefreshData()

            READER.Close()
            MysqlConn.Close()
        Catch ex As MySqlException
            MessageBox.Show(ex.Message)
        Finally
            MysqlConn.Dispose()
            COMMAND.Dispose()
        End Try

    End Sub

    Private Sub btnRefresh_Click(sender As Object, e As EventArgs) Handles btnRefresh.Click
        MysqlConn = New MySqlConnection
        MysqlConn.ConnectionString = "Server=localhost;Uid=root;Pwd=;Database=ilycean;"
        Dim SDA As New MySqlDataAdapter
        Dim dbDataSet As New DataTable
        Dim bSource As New BindingSource

        Try
            MysqlConn.Open()
            Dim Query As String
            Query = "select * from ilycean.users"
            COMMAND = New MySqlCommand(Query, MysqlConn)
            SDA.SelectCommand = COMMAND
            SDA.Fill(dbDataSet)
            bSource.DataSource = dbDataSet
            dataGridViewAdminAccounts.DataSource = bSource
            SDA.Update(dbDataSet)

            txtID.ResetText()
            txtName.ResetText()
            txtEmail.ResetText()
            txtPassword.ResetText()
            RefreshData()

            MysqlConn.Close()
        Catch ex As MySqlException
            MessageBox.Show(ex.Message)
        Finally
            MysqlConn.Dispose()
        End Try

    End Sub

    Private Sub loadTable()

        MysqlConn = New MySqlConnection
        MysqlConn.ConnectionString = "Server=localhost;Uid=root;Pwd=;Database=ilycean;"
        Dim SDA As New MySqlDataAdapter

        Dim bSource As New BindingSource

        Try
            MysqlConn.Open()
            Dim Query As String
            Query = "select * from ilycean.users"
            COMMAND = New MySqlCommand(Query, MysqlConn)
            SDA.SelectCommand = COMMAND
            SDA.Fill(dbDataSet)
            bSource.DataSource = dbDataSet
            dataGridViewAdminAccounts.DataSource = bSource
            SDA.Update(dbDataSet)

            MysqlConn.Close()
        Catch ex As MySqlException
            MessageBox.Show(ex.Message)
        Finally
            MysqlConn.Dispose()
        End Try

    End Sub


    Private Sub dataGridViewAdminAccounts_CellContentClick(sender As Object, e As DataGridViewCellEventArgs) Handles dataGridViewAdminAccounts.CellContentClick
        If e.RowIndex >= 0 Then
            Dim row As DataGridViewRow
            row = Me.dataGridViewAdminAccounts.Rows(e.RowIndex)

            txtID.Text = row.Cells("id").Value.ToString
            txtName.Text = row.Cells("name").Value.ToString
            txtEmail.Text = row.Cells("email").Value.ToString
            txtPassword.Text = row.Cells("password").Value.ToString

        End If
    End Sub

    Private Sub txtSearch_TextChanged(sender As Object, e As EventArgs) Handles txtSearch.TextChanged
        Dim DV As New DataView(dbDataSet)
        DV.RowFilter = String.Format("name Like'%0%'", txtSearch.Text)

        dataGridViewAdminAccounts.DataSource = DV

    End Sub

    Private Sub manageAdminAccounts_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
        Dim dialog As DialogResult
        dialog = MessageBox.Show("Do you really want to exit?", "Exit", MessageBoxButtons.YesNo)
        If dialog = DialogResult.No Then
            e.Cancel = True
        Else
            Application.ExitThread()
        End If
    End Sub

    Private Sub manageAdminAccounts_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        loadTable()
        txtID.ResetText()
        txtName.ResetText()
        txtEmail.ResetText()
        txtPassword.ResetText()
        txtPassword.ResetText()
    End Sub

    Public Sub RefreshData()
        Dim Query As String
        Query = "select * from ilycean.users"
        dbDataSet.Clear()
        COMMAND = New MySqlCommand(Query, MysqlConn)
        SDA.SelectCommand = COMMAND
        SDA.Fill(dbDataSet)
        dataGridViewAdminAccounts.DataSource = dbDataSet

    End Sub

End Class

每次我InsertUpdateDelete时,都会不断出现以下错误:

已经有一个打开的 DataReader 与此命令关联,必须先关闭。

我已经尝试在我的连接字符串上添加MultipleActiveResultSets=True;,但它仍然不起作用。

【问题讨论】:

我会考虑为您的所有MySQL 对象实现UsingUsing COMMAND As New MySQLCommand(Query, MysqlConn)。还要考虑使用参数来避免 SQL 注入。此外,在您的插入、删除和更新中,您没有选择数据,因此您不需要阅读器。而是使用COMMAND.ExecuteNonQuery() @Bugs 谢谢你成功了! 【参考方案1】:

ExecuteReader 中使用CommandBehavior.CloseConnection 作为

MySqlDataReader myReader = myCommand.ExecuteReader(CommandBehavior.CloseConnection);

同样使用using 构造也适用于非托管资源,例如 SQL 连接

Using resource As New resourceType   
    ' Insert code to work with resource.  
End Using  

【讨论】:

以上是关于尝试插入、更新或删除时出错:已经有一个打开的 DataReader 与此命令关联,必须先关闭的主要内容,如果未能解决你的问题,请参考以下文章

使用 DataGrid 更新访问表时出错

单击按钮时出错:NameError: name is not defined

数据库中的成功快照表。但是当有事件插入、更新或删除时不能CDC

无法将Delphi ADOQuery更新或插入到Excel工作表中

专业版win10想开测试模式,提示“设置元素数据时出错。 该值受安全引导策略保护无法进行修改或删除

使用T-SQL语句插入更新删除数据表