【问题标题】:Ms Access - System resource exceeded inserting rowsMs Access - 系统资源超出插入行
【发布时间】:2015-07-20 17:37:28
【问题描述】:

我想从 vb.net datagridview 向 Ms access 数据库插入 1500 行。

插入最多 400 行没有问题,但超过 400 行则显示错误 - 超出系统资源。

我使用下面的代码。错误突出显示为:

readinputs = dbup.ExecuteReader() and sometimes
.ExecuteNonQuery()

Dim Dbcon As New OleDbConnection(connStr)

Dbcon.Open()

Dim query As String
Dim dbup As New OleDbCommand
Dim readinputs As OleDbDataReader

For x As Integer = 0 To IncomingMailDGV.Rows.Count - 1
    Dim received As String = IncomingMailDGV.Rows(x).Cells(0).Value
    Dim subject As String = IncomingMailDGV.Rows(x).Cells(1).Value
    Dim contents As String = IncomingMailDGV.Rows(x).Cells(2).Value

    query = "SELECT ReceivedDateTime, Subject, MessageContents FROM IncomingAlerts WHERE ReceivedDateTime = @ReceivedDateTime AND MessageContents =@MessageContents"
    dbup = New OleDbCommand(query, Dbcon)
    dbup.Parameters.AddWithValue("ReceivedDateTime", received)
    dbup.Parameters.AddWithValue("MessageContents", contents)
    readinputs = dbup.ExecuteReader()

    If readinputs.HasRows = False Then

        Dim InsertData As String
        InsertData = "INSERT INTO IncomingAlerts(ReceivedDateTime, Subject, MessageContents) Values (@ReceivedDateTime, @Subject, @MessageContents)"
        dbup = New OleDbCommand(InsertData)
        dbup.Parameters.AddWithValue("ReceivedDateTime", received)
        dbup.Parameters.AddWithValue("Subject", subject)
        dbup.Parameters.AddWithValue("MessageContents", contents)

        With dbup
            .CommandText = InsertData
            .Connection = Dbcon
            .ExecuteNonQuery()
        End With

    End If

Next

【问题讨论】:

    标签: .net vb.net ms-access datagridview oledb


    【解决方案1】:

    由于循环,您每行最多创建 2 个OleDbCommand 对象(一个用于SELECT,可能一个用于UPDATE),但永远不会丢弃它们。您可以使用cmd.Parameters.Clear 重用它们,但我会将其拆分为控制程序以使其更简单。 类似的东西

    ' if AllowUsersToAddRows is true, this will loop one too many:
    For x As Integer = 0 To IncomingMailDGV.Rows.Count - 1
        Dim received = IncomingMailDGV.Rows(x).Cells(0).Value.ToString
        Dim contents  = IncomingMailDGV.Rows(x).Cells(2).Value.ToString
        Dim subject  = IncomingMailDGV.Rows(x).Cells(1).Value.ToString
    
        If ItemExists(received, contents) = False Then
            InsertItem(received, contents, subject)
        End If
    Next
    

    然后是自包含并自行清理的助手:

    Private Function ItemExists(received As String, 
           contents As String) As Boolean
        Dim query As String = "SELECT ReceivedDateTime, Subject, MessageContents FROM IncomingAlerts WHERE ReceivedDateTime = @ReceivedDateTime AND MessageContents =@MessageContents"
        Using dbcon As New OleDbConnection(connstr)
            dbcon.Open
            Using cmd As New OleDbCommand(query, dbcon)
                cmd.Parameters.AddWithValue(("ReceivedDateTime", received)
                cmd.Parameters.AddWithValue("MessageContents", contents)
    
                ' Better to convert the query to a SELECT COUNT
                ' cmd.ExecuteScalar would not require a Reader
                Using rdr = cmd.ExecuteReader
                    Return rdr.HasRows
                End Using
            End Using    
        End Using
    
    End Function
    
    Private Function InsertItem(received As String, 
                     contents As String, subj As String) As Boolean
        Dim sql = "INSERT INTO IncomingAlerts(ReceivedDateTime, Subject, MessageContents) Values (@ReceivedDateTime, @Subject, @MessageContents)"
    
        Dim rows As Integer
        Using dbcon As New OleDbConnection(connstr)
            Using cmd As New OleDbCommand(sql, dbcon)
                dbcon.Open
                cmd.Parameters.AddWithValue("@ReceivedDateTime", received)
                cmd.Parameters.AddWithValue("@Subject", subj)
                cmd.Parameters.AddWithValue("@MessageContents", contents)
                rows = cmd.ExecuteNonQuery
                Return rows <> 0
            End Using
        End Using
    End Function
    

    我还通过使用构造函数重载使它们更短。例如,使用 OleDbCommand,我在创建 SQL 时将其传递给它,而不是单独设置这些属性。

    按原样,它只完成一次。您还可以执行其他操作,例如仅使用 SQL Count 来确定是否有任何匹配的行等。使用 DataTable 和 FindRow 还可以避免必须通过热数据库来查看是否存在某些内容。

    主要点是处理完ConnectionCommandDataReader 对象。

    【讨论】:

    • 非常感谢 Plutonix!它现在可以正常工作了。
    • 很高兴听到。任何具有Dispose 方法的东西都可以(通常)放入Using 块中,以便在您的代码完成后处理资源。对于 dbConnections,它会关闭并处理它们。
    猜你喜欢
    • 2021-10-03
    • 2013-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多