Ms Access - 系统资源超出了插入行

时间:2015-07-20 17:37:29

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

我想从vb.net datagridview向Ms访问数据库插入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

1 个答案:

答案 0 :(得分:2)

由于循环,您每行最多创建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及其连接,而不是单独设置这些属性。

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

点在您完成后会处置ConnectionCommandDataReader个对象。