【问题标题】:error There is already an open DataReader associated with this Connection which must be closed first错误 已经有一个打开的 DataReader 与此 Connection 关联,必须先关闭
【发布时间】:2021-06-14 15:54:21
【问题描述】:

你们能帮帮我吗?

Private Sub BtnSimpan_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnSimpan.Click
        If BtnSimpan.Text = "&Simpan" Then
            If txtKode.Text = "" Then
                MsgBox("Kode Harus Di isi", MsgBoxStyle.Exclamation, "Peringatan")
                txtKode.Focus()
                Exit Sub
            End If
            Call bukaDB()
            CMD = New MySqlCommand("SELECT KodeBarang from tabelbarang WHERE KodeBarang = '" & txtKode.Text & "'", Conn)
            RD = CMD.ExecuteReader()
            RD.Read()
            If RD.HasRows Then
                MsgBox("Maaf, Data dengan Kode tersebut telah ada", MsgBoxStyle.Exclamation, "Peringatan")
            Else
                simpan = "INSERT INTO tabelbarang (KodeBarang,NamaBarang,HargaBeli,HargaJual,Stok) VALUES ('" & txtKode.Text & "','" & txtNamaBarang.Text & "','" & txtHargaBeli.Text & "','" & txtHargaJual.Text & "','" & txtStok.Text & "')"
                CMD = New MySqlCommand(simpan, Conn)
                CMD.ExecuteNonQuery() 
                Call isiGrid()
                BtnSimpan.Text = "&Tambah"
                Call Bersih()
            End If
        Else
            BtnSimpan.Text = "&Simpan"
            'Call Bersih()
            txtKode.Enabled = True
            txtNamaBarang.Enabled = True
            txtHargaBeli.Enabled = True
            txtHargaJual.Enabled = True
            txtStok.Enabled = True
            txtKode.Focus()
        End If
End Sub

【问题讨论】:

  • 欢迎来到 Stack Overflow!请阅读How do I ask a good question?
  • 哎呀,这看起来很可怕——容易受到 sql 注入问题的影响!此外,没有人 不再使用Call。关键字的唯一目的是保持与从 VB6 时代向前移植的旧代码的兼容性。
  • @JoelCoehoorn 郑重声明,我偶尔还是会用Call,但我不会假装符合“现代”风格。

标签: vb.net


【解决方案1】:

问题的代码中有几个过时的做法。下面的代码针对现代编码风格进行了更新,仅仅使用现代风格的行为也将解决问题中的问题......也就是说,如果你从一开始就遵循良好的编码实践,这整个问题就解决了你永远不会遇到这个问题。

这还解决了原始版本中的巨大的安全问题,如果只是为了跟上现代编码标准,就可以完全避免这种问题。

Private Sub BtnSimpan_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnSimpan.Click

    If BtnSimpan.Text = "&Simpan" AndAlso String.IsNullOrWhitespace(txtKode.Text)  Then
        MsgBox("Kode Harus Di isi", MsgBoxStyle.Exclamation, "Peringatan")
        txtKode.Focus()
        Exit Sub
    End If

    If BtnSimpan.Text <> "&Simpan" Then
        BtnSimpan.Text = "&Simpan"
        'Bersih()
        txtKode.Enabled = True
        txtNamaBarang.Enabled = True
        txtHargaBeli.Enabled = True
        txtHargaJual.Enabled = True
        txtStok.Enabled = True
        txtKode.Focus()
        Exit Sub
    End If

    'Do NOT try to re-use the same connection throughout your application!
    ' It really is more efficient to create a brand new object for most queries,
    '  and only share the connection string.

    'Also, JUST DO THE INSERT.
    'Make sure there is a unique constraint on the KodeBarang column,
    ' and handle the exception if it fails.

    ' Correct for *either one* of the above issues, and the
    ' problem in the question never would have happened.
 
    Try
        Using CN As New MySqlConnection("Connection string here"), _
              CMD As New MySqlCommand("INSERT INTO tabelbarang (KodeBarang,NamaBarang,HargaBeli,HargaJual,Stok) VALUES (@KodeBarang, @NamaBarang, @HargaBeli, @HargaJual, @Stok)", CN)

            CMD.Parameters.AddWithValue("@KodeBarang", txtKode.Text)
            CMD.Parameters.AddWithValue("@NamaBarang", txtNamaBarang.Text)
            CMD.Parameters.AddWithValue("@HargaBeli", txtHargaBeli.Text)
            CMD.Parameters.AddWithValue("@HargaJual", txtHargaJual.Text)
            CMD.Parameters.AddWithValue("@Stok", txtStok.Text)   

            CN.Open()
            CMD.ExecuteNonQuery() 
        End Using

        isiGrid()
        BtnSimpan.Text = "&Tambah"
    Catch ex As MySqlException When ex.Code = 1062 '1062 is Duplicate Key Violation
        MsgBox("Maaf, Data dengan Kode tersebut telah ada", MsgBoxStyle.Exclamation, "Peringatan")
    End Try
End Sub

【讨论】:

  • @Jimi 事实证明,MySql 连接器处理推理的方式不同,因此该数据库是安全的。
  • 我假设你参考了这个Start Using AddWithValue。在你的帖子中仍然有点奇怪(这就是为什么会有一点微笑)。
  • @Jimi 那是我见过的一个地方。还有一些其他人解释了为什么 MySql 大多是免疫的。是的,通常我仍然更喜欢在我的数据库类型中明确说明,但我觉得我已经对可怜的灵魂投入了足够多的东西:)
  • @Mary 我相信是这样,因为它与库无关,因为它是用于与 MySql 服务通信的底层原生格式。
猜你喜欢
  • 1970-01-01
  • 2019-01-17
  • 2020-09-25
  • 2011-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-25
  • 2011-07-23
相关资源
最近更新 更多