2015-07-20 51 views
1

我想向vb.net datagridview的Ms访问数据库插入1500行。Ms Access - 系统资源超出插入行

插入多达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 [email protected]" 
    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 

回答

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 [email protected]" 
    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对象。

+0

非常感谢你Plutonix !.它现在工作正常。 –

+0

很好听。任何具有Dispose方法的东西都可以(通常)放入一个'Using'块中,以便在代码完成时处理资源。在dbConnections的情况下,它关闭并处理它们。 – Plutonix