Diese Situation ist nicht ungewöhnlich, wenn sie mit Masseneinfügungen zu ODBC verknüpften Tabellen in Access handelt. Im Falle der folgenden Access-Abfrage
INSERT INTO METER_DATA (MPO_REFERENCE)
SELECT MPO_REFERENCE FROM tblTempSmartSSP
wo [METER_DATA] eine ODBC-verknüpfte Tabelle ist und [tblTempSmartSSP] ist eine lokale (nativ) Access-Tabelle, wird ODBC etwas begrenzt, wie klug es sein kann, weil es in der Lage sein, eine breite Palette von Zieldatenbanken unterzubringen, deren Fähigkeiten stark variieren können. Leider bedeutet dies oft, dass trotz der einzelnen Access SQL-Anweisung, die tatsächlich an die entfernte (verknüpfte) Datenbank gesendet wird, eine separate INSERT (oder gleichwertige) für jede Zeile in der lokalen Tabelle ist. Verständlicherweise kann sich dies als sehr langsam erweisen, wenn die lokale Tabelle eine große Anzahl von Zeilen enthält.
Option 1: Gebürtige bulk Einsätze in die entfernten Datenbank
Alle Datenbanken einen oder mehr nativen Mechanismen für den Bulk-Laden von Daten haben: Microsoft SQL Server hat „bcp“ und BULK INSERT
und Oracle hat „SQL * Lader ". Diese Mechanismen sind für den Massenbetrieb optimiert und bieten normalerweise erhebliche Geschwindigkeitsvorteile. In der Tat, wenn die Daten in Access importiert und "massiert" werden müssen, bevor sie in die entfernte Datenbank übertragen werden, kann es noch schneller sein, die modifizierten Daten wieder in eine Textdatei zu exportieren und dann in die entfernte Datenbank zu importieren.
Option 2: eine Pass-Through-Abfrage in Access Mit
Wenn die Bulk-Import-Mechanismen keine gangbare Option sind, dann ist eine weitere Möglichkeit, eine oder mehrere bauen Abfragen in Access-Pass-Through die zum Hochladen Daten mit INSERT-Anweisungen, die mehr als eine Zeile gleichzeitig einfügen können.
Zum Beispiel, wenn die entfernte Datenbank SQL Server ist (2008 oder später), dann könnten wir eine Access-Pass-Through (T-SQL) Abfrage wie diese
INSERT INTO METER_DATA (MPO_REFERENCE) VALUES (1), (2), (3)
einzufügen drei Reihen mit einer INSERT laufen Erklärung.
Nach einer Antwort auf eine andere Frage von vorhin here die entsprechende Syntax für Oracle wäre
INSERT ALL
INTO METER_DATA (MPO_REFERENCE) VALUES (1)
INTO METER_DATA (MPO_REFERENCE) VALUES (2)
INTO METER_DATA (MPO_REFERENCE) VALUES (3)
SELECT * FROM DUAL;
ich diesen Ansatz mit SQL Server getestet (wie ich haben keinen Zugang zu einer Oracle-Datenbank) unter Verwendung eines nativen [tblTempSmartSSP] Tabelle mit 10.000 Zeilen. Der Code ...
Sub LinkedTableTest()
Dim cdb As DAO.Database
Dim t0 As Single
t0 = Timer
Set cdb = CurrentDb
cdb.Execute _
"INSERT INTO METER_DATA (MPO_REFERENCE) " & _
"SELECT MPO_REFERENCE FROM tblTempSmartSSP", _
dbFailOnError
Set cdb = Nothing
Debug.Print "Elapsed time " & Format(Timer - t0, "0.0") & " seconds."
End Sub
... dauerte ungefähr 100 Sekunden, um in meiner Testumgebung ausgeführt zu werden.
dagegen der folgende Code, die wie oben beschrieben mehrreihigen INSERTs aufbaut (was unter Verwendung von Microsoft aufruft Table Value Constructor a) ...
Sub PtqTest()
Dim cdb As DAO.Database, rst As DAO.Recordset
Dim t0 As Single, i As Long, valueList As String, separator As String
t0 = Timer
Set cdb = CurrentDb
Set rst = cdb.OpenRecordset("SELECT MPO_REFERENCE FROM tblTempSmartSSP", dbOpenSnapshot)
i = 0
valueList = ""
separator = ""
Do Until rst.EOF
i = i + 1
valueList = valueList & separator & "(" & rst!MPO_REFERENCE & ")"
If i = 1 Then
separator = ","
End If
If i = 1000 Then
SendInsert valueList
i = 0
valueList = ""
separator = ""
End If
rst.MoveNext
Loop
If i > 0 Then
SendInsert valueList
End If
rst.Close
Set rst = Nothing
Set cdb = Nothing
Debug.Print "Elapsed time " & Format(Timer - t0, "0.0") & " seconds."
End Sub
Sub SendInsert(valueList As String)
Dim cdb As DAO.Database, qdf As DAO.QueryDef
Set cdb = CurrentDb
Set qdf = cdb.CreateQueryDef("")
qdf.Connect = cdb.TableDefs("METER_DATA").Connect
qdf.ReturnsRecords = False
qdf.sql = "INSERT INTO METER_DATA (MPO_REFERENCE) VALUES " & valueList
qdf.Execute dbFailOnError
Set qdf = Nothing
Set cdb = Nothing
End Sub
... nahmen zwischen 1 und 2 Sekunden, um das gleiche zu erzeugen, Ergebnisse.
(T-SQL-Tabellenwert Konstrukteurs sind Einfügen 1000 Zeilen zu einer Zeit begrenzt, so dass der obige Code ein bisschen komplizierter, als es sonst wäre ist.)
Meter_Data ist eine Oracle-Datenbank-Tabelle –