Ms Access - 系统资源超出插入行
Ms Access - System resource exceeded inserting rows
我想从 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
由于循环,您每行最多创建 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 还可以避免必须热数据库以查看是否存在某些内容。
main 点是处理 Connection
、Command
和 DataReader
对象。
我想从 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
由于循环,您每行最多创建 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 还可以避免必须热数据库以查看是否存在某些内容。
main 点是处理 Connection
、Command
和 DataReader
对象。