Ta sytuacja nie jest niczym niezwykłym gdy ma do czynienia z luzem wstawki ODBC tabel połączonych w programie Access. W przypadku następującego zapytania dostępu
INSERT INTO METER_DATA (MPO_REFERENCE)
SELECT MPO_REFERENCE FROM tblTempSmartSSP
gdzie [METER_DATA] jest ODBC połączone stół i [tblTempSmartSSP] jest lokalnym (Ojczysty) tabeli Access ODBC jest nieco ograniczona w sposób mądry to może być dlatego, że ma być w stanie pomieścić szeroki zakres docelowych baz danych, których możliwości mogą się znacznie różnić. Niestety, często oznacza to, że pomimo pojedynczej instrukcji Access SQL to, co faktycznie jest wysyłane do zdalnej (połączonej) bazy danych, to osobny INSERT (lub odpowiednik) dla każdego wiersza w lokalnej tabeli. Zrozumiałe jest, że może się to okazać bardzo powolne, jeśli lokalna tabela zawiera dużą liczbę wierszy.
Wariant 1: Native wkładki luzem do zdalnej bazy danych
Wszystkie bazy danych mają jeden lub więcej natywnych mechanizmów załadunku luzem danych: Microsoft SQL Server ma „BCP” i BULK INSERT
, a Oracle ma „SQL *Ładowarka". Te mechanizmy są zoptymalizowane pod kątem operacji masowych i zwykle oferują znaczące zalety szybkości. W rzeczywistości, jeśli dane muszą być importowane do programu Access i "masowane" przed przeniesieniem do zdalnej bazy danych, nadal można szybciej zrzucić zmodyfikowane dane z powrotem do pliku tekstowego, a następnie zbiorczo zaimportować je do zdalnej bazy danych.
Opcja 2: Za pomocą kwerendy przekazującej w dostępie
Jeśli mechanizmy importu luzem nie są realną opcją, to inną możliwością jest stworzenie jednego lub więcej kwerend przekazujących w dostępie do przesłania dane za pomocą instrukcji INSERT, które mogą wstawiać więcej niż jeden wiersz naraz.
Na przykład, jeśli zdalna baza danych była SQL Server (2008 lub później), to możemy uruchomić dostęp pass-through (T-SQL) kwerendy jak ten
INSERT INTO METER_DATA (MPO_REFERENCE) VALUES (1), (2), (3)
wstawić trzy wiersze z jednej INSERT komunikat.
Zgodnie z odpowiedzią na innym wcześniejszym pytaniu here odpowiednia składnia Oracle byłoby
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;
testowałem tej metody z SQL Server (jak nie mam dostępu do bazy danych Oracle), używając rodzimego Tabela [tblTempSmartSSP] z 10 000 wierszy. Kod ...
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
... wykonano około 100 sekund w moim środowisku testowym.
Natomiast poniższy kod, który buduje wstawia wielorzędowe jak opisano powyżej (przy użyciu co nazywa Microsoft Table Value Constructor) ...
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
... trwało od 1 do 2 sekund, aby produkować takie same wyniki.
(T-SQL tabeli wartości konstruktorzy ograniczony do wkładania 1000 wierszy na raz, tak więc powyższy kod jest bardziej skomplikowany niż byłoby to w inny sposób).
Meter_Data jest stół bazie wyrocznią –