2015-07-20 44 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