С этим соединением уже есть открытый Data Reader, который должен быть закрыт первым vb. net .vb - PullRequest
0 голосов
/ 06 марта 2020
Dim Conn As MySqlConnection
Dim Command As MySqlCommand
Dim Reader As MySqlDataReader
Dim server As String = "serverxxxxxxxx.1;user=root;database=xxxxxxxxx"

Public Sub testing()
    Conn = New MySqlConnection
    Conn.ConnectionString = server
    Dim datecompare As String = Date.Today.ToString("yyyy-MM-dd hh:mm:ss")
    Dim primarykey1 As String = ""
    Dim primarykey2 As String = ""
    Try
        If Not Conn.State = ConnectionState.Open Then
            Conn.Open()
        End If

        Dim Query1 As String
        Query1 = "Select * From `tblborrow` Where `DueDate` = '" & datecompare & "'"
        Command = New MySqlCommand(Query1, Conn)
        Reader = Command.ExecuteReader
        While Reader.Read
            primarykey1 = Reader.GetInt32("BorrowID")

            Try
                If Not Conn.State = ConnectionState.Open Then
                    Conn.Open()
                End If

                Dim query2 As String
                query2 = "Update `tblborrow` Set `Remarks` = '" & "Due Date" & "' Where `BorrowID` = '" & primarykey1 & "'"
                Command = New MySqlCommand(query2, Conn)
                Reader = Command.ExecuteReader
                Reader.Close()
                Conn.Close()
            Catch ex As Exception
                MsgBox(ex.Message)
            End Try
            'end of duedate
        End While
        Reader.Close()
        Conn.Close()
    Catch ex As Exception
        MsgBox(ex.Message)
    End Try

    'for OVER DUE
    Try
        If Not Conn.State = ConnectionState.Open Then
            Conn.Open()
        End If

        Dim Query1 As String
        Query1 = "Select * From `tblborrow` Where `DueDate` < '" & datecompare & "'"
        Command = New MySqlCommand(Query1, Conn)
        Reader = Command.ExecuteReader
        While Reader.Read
            primarykey2 = Reader.GetInt32("BorrowID")

            Try
                If Not Conn.State = ConnectionState.Open Then
                    Conn.Open()
                End If
                Dim query2 As String
                query2 = "Update `tblborrow` Set `Remarks` = '" & "Over Due" & "' Where `BorrowID` = '" & primarykey2 & "'"
                Command = New MySqlCommand(query2, Conn)
                Reader = Command.ExecuteReader
                Reader.Close()
                Conn.Close()
            Catch ex As Exception
                MsgBox(ex.Message)
            End Try
            'end of Over Due
        End While
        Reader.Close()
        Conn.Close()
    Catch ex As Exception
        MsgBox(ex.Message)
    End Try
End Sub

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Call testing()
End Sub

Я создал subli c publi, который будет выбирать и обновлять примечания в моей базе данных на основе borrowID (это автоматическое увеличение). Сохранение даты в DueDate и сравнение, которое я объявляю с текущим временем сегодня, но каждый раз, когда я нажимаю кнопку, где я сохранил код, я получаю эту ошибку There is already an open DataReader associated with this connection which must be closed first Я дважды проверял свой код и не пропустил ставить reader.close() после каждого conn.close() или я не знаю, может быть, я пропустил .. Я попробовал несколько изменений в моем коде, но все равно я получаю ту же ошибку. Может ли кто-нибудь помочь мне и построить мой код? .. спасибо.

Ответы [ 3 ]

0 голосов
/ 06 марта 2020

Вы пытаетесь открыть 2 считывателя на одном соединении. См. Стрелки с двумя головками.

Reader = Command.ExecuteReader'<<----
        While Reader.Read
            primarykey1 = Reader.GetInt32("BorrowID")

            Try
                If Not Conn.State = ConnectionState.Open Then
                    Conn.Open()
                End If

                Dim query2 As String
                query2 = "Update `tblborrow` Set `Remarks` = '" & "Due Date" & "' Where `BorrowID` = '" & primarykey1 & "'"
                Command = New MySqlCommand(query2, Conn)
                Reader = Command.ExecuteReader '<<----

Если вы разбиваете свой код на логические единицы, когда в каждом методе происходит только одна вещь, будет немного легче увидеть, где что-то не так go.

Хранение объектов вашей базы данных локально по отношению к методам, в которых они используются, позволяет вам быть уверенными, что они закрыты и удалены. Using...End Using блоки обрабатывают это для вас, даже если есть ошибка.

Обратите внимание, что в 2 методах обновления параметры добавляются за пределы For l oop и устанавливается только значение, которое изменяется внутри л oop.

Dim ConString As String = "serverxxxxxxxx.1;user=root;database=xxxxxxxxx"

Public Sub GetPKs()
    Dim pkList As New List(Of Integer)
    Dim DueDate As String = Date.Today.ToString("yyyy-MM-dd hh:mm:ss")
    Using Conn As New MySqlConnection(ConString),
            cmd As New MySqlCommand("Select BorrowID From tblborrow Where DueDate = @DueDate")
        cmd.Parameters.Add("@DueDate", MySqlDbType.VarChar, 100).Value = DueDate
        Conn.Open()
        Using reader As MySqlDataReader = cmd.ExecuteReader
            While reader.Read
                pkList.Add(reader.GetInt32("BorrowID"))
            End While
        End Using
    End Using
    UpdateRemarks(pkList, DueDate)
End Sub

Private Sub UpdateRemarks(pks As List(Of Integer), DueDate As String)
    Using con As New MySqlConnection(ConString),
            cmd As New MySqlCommand("Update tblborrow Set Remarks = @DueDate Where BorrowID = @PK", con)
        With cmd.Parameters
            .Add("@DueDate", MySqlDbType.VarChar, 100).Value = DueDate
            .Add("@PK", MySqlDbType.Int32)
        End With
        con.Open()
        For Each i In pks
            cmd.Parameters("@PK").Value = i
            cmd.ExecuteNonQuery()
        Next
    End Using
End Sub

Private Sub GetOverduePKs()
    Dim pkList As New List(Of Integer)
    Using cn As New MySqlConnection(ConString),
            cmd As New MySqlCommand("Select BorrowID From tblborrow Where DueDate < @DueDate")
        cmd.Parameters.Add("@DueDate", MySqlDbType.VarChar, 100).Value = Date.Today.ToString("yyyy-MM-dd hh:mm:ss")
        cn.Open()
        Using reader = cmd.ExecuteReader
            While reader.Read
                pkList.Add(reader.GetInt32("BorrowID"))
            End While
        End Using
    End Using
    UpdateOverdueRemarks(pkList)
End Sub

Private Sub UpdateOverdueRemarks(pks As List(Of Integer))
    Using cn As New MySqlConnection(ConString),
            cmd As New MySqlCommand("Update tblborrow Set Remarks = 'Over Due' Where BorrowID = @PK")
        cmd.Parameters.Add("@PK", MySqlDbType.Int32)
        cn.Open()
        For Each i In pks
            cmd.Parameters("@PK").Value = i
            cmd.ExecuteNonQuery()
        Next
    End Using
End Sub

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    GetPKs()
    GetOverduePKs()
End Sub
0 голосов
/ 06 марта 2020

используйте 2 соединения CONN и CONN2, с одинаковыми параметрами, используйте CONN, чтобы открыть считыватель QUERY1. Во время чтения используйте CONN2 для создания второго запроса. Обратите внимание, что это работает для MySQL. MS-Access может обрабатывать несколько команд в одном соединении, MySql не может и нуждается в отдельных соединениях. Sqlite не может обрабатывать 2 одновременных соединения. там вы должны использовать в incore временный массив или список. Из рабочей программы:

   Dim DbConn As New MySqlConnection(SqlProv)
   Dim DbConn2 As New MySqlConnection(SqlProv)

-

    Dim SQLsfSelect As String = "SELECT CollSeq FROM ToBeIndexed WHERE CollCode = @CollCode"
    Dim DRsfSelect As MySqlDataReader = Nothing
    Dim DCsfSelect As MySqlCommand
    Dim sfSelP1 As New MySqlParameter("@CollCode", MySqlDbType.VarChar, 4)
    DCsfSelect = New MySqlCommand(SQLsfSelect, DbConn)

-

    Dim SQLasSelect As String = "SELECT DISTINCT CollSeq FROM Data WHERE CollCode = @CollCode ORDER BY CollSeq"
    Dim DRasSelect As MySqlDataReader = Nothing
    Dim DCasSelect As MySqlCommand
    Dim asSelP1 As New MySqlParameter("@CollCode", MySqlDbType.VarChar, 4)
    DCasSelect = New MySqlCommand(SQLasSelect, DbConn2)

-

DbConn.Open()
        sfSelP1.Value = CurCollCode
        CollSeqToIdxC.Clear()
        Try
            DRsfSelect = DCsfSelect.ExecuteReader()
            Do While (DRsfSelect.Read())
                CollSeq = GetDbIntegerValue(DRsfSelect, 0)
                DbConn2.Open()
                asSelP1.Value = CurCollCode
                Try
                    DRasSelect = DCasSelect.ExecuteReader()
                    Do While (DRasSelect.Read())
                        CollSeq = GetDbIntegerValue(DRasSelect, 0)
                        CollSeqToIdxC.Add(CollSeq, CStr(CollSeq))
                    Loop
                Catch ex As Exception
                    MsgBox(ex.ToString(), , SysMsg1p(402, CurCollCode))
                Finally
                    If Not (DRasSelect Is Nothing) Then
                         DRasSelect.Close()
                    End If
                End Try
                DbConn2.Close()
            Loop
        Catch ex As Exception
            MsgBox(ex.ToString(), , SysMsg1p(403, CurCollCode))
        Finally
            If Not (DRsfSelect Is Nothing) Then
                DRsfSelect.Close()
            End If
        End Try
        DbConn.Close()
0 голосов
/ 06 марта 2020

Попробуйте использовать другую переменную для читателей, возможно Reader1 и Reader2. Вероятно, это связано с тем, что вы использовали один и тот же читатель для выполнения другого запроса, и, следовательно, уже открылась ошибка чтения данных.

Вы пытаетесь открыть ту же книгу, которая уже открыта. По крайней мере, сделайте это другой книгой.

...