Access Design:RunSQL oder Execute

Aus DBWiki
Wechseln zu: Navigation, Suche

Sollte man Aktionsabfragen mit RunSQL oder mit der Execute-Methode ausführen?

Bei Execute

  • muss man nicht mit SetWarnings True/False arbeiten
  • ist eine Fehlerbehandlung per dbFailOnError möglich
  • ist performanter als RunSQL (siehe unten)
  • man kann explizite Transaktionen verwenden
  • kann man hinterher die RecordsAffected-Eigenschaft auswerten
  • ist es möglich, über die entsprechenden Connection-Objekte auch auf externe Datenbanken zuzugreifen (Upsizing auf einen SQL-Server ist also prinzipiell möglich - hat natürlich seine eigenen Tücken....)

Ein Argument für RunSQL ist, dass man die Datenzugriffsobjekte nicht explizit angeben muss (ist aber bei näherer Betrachtung eher ein Argument für Execute, denn dann kann und muss man den Datenzugriff sauber ausprogrammieren!)

Leistungsvergleich

Unter Access 97 (Messreihe 1) und Access 2003 (Messreihe 2) wurden folgende Messwerte ermittelt:

Methode Messreihe 1 (Sekunden) Messreihe 2 (Sekunden)
RunSQL 2,503906 0,28125
Execute 1,339844 0,046875
Execute (eigener Jet WS) 1,292969 0,03125
Execute (ADO) 1,851563 0,09375

Testfunktion

Public Function TestRunSQLExecute()
Dim I As Long, J As Long, Z As Single, DB As Object, WS As DAO.Workspace
  Const SQL1 = "Create Table zzz (Test text(50), lTest Long)"
  Const SQL2 = "INSERT INTO zzz (lTest) Values(999)"
  Const SQL3 = "Insert into zzz (Test) Select Nachname from MeineTabelle"
  Const SQL4 = "Drop Table zzz"
 
Z = Timer
DoCmd.SetWarnings False
For J = 1 To 10
  DoCmd.RunSQL SQL1
  For I = 1 To 10
    DoCmd.RunSQL SQL2
  Next I
  DoCmd.RunSQL SQL3
  DoCmd.RunSQL SQL4
Next J
DoCmd.SetWarnings True
Debug.Print "RunSQL: " & Timer - Z & " s"
 
Z = Timer
Set DB = CurrentDb
For J = 1 To 10
  DB.Execute SQL1
  For I = 1 To 10
    DB.Execute SQL2
  Next I
  DB.Execute SQL3
  DB.Execute SQL4
Next J
Debug.Print "Execute: " & Timer - Z & " s"
 
Z = Timer
Set WS = DBEngine.CreateWorkspace("Ws", "Admin", "", dbUseJet)
Set DB = WS.OpenDatabase(CurrentDb.Name)
For J = 1 To 10
  DB.Execute SQL1
  For I = 1 To 10
    DB.Execute SQL2
  Next I
  DB.Execute SQL3
  DB.Execute SQL4
Next J
Debug.Print "Execute (Jet WS): " & Timer - Z & " s"
Set DB = Nothing
Set WS = Nothing
 
Z = Timer
Set DB = New ADODB.Connection
  DB.Open "Provider=Microsoft.Jet.OLEDB.3.51;Data Source=" & CurrentDb.Name & ";"
  'aktuell sollte man vermutlich folgende Zeile verwenden:
  'DB.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & CurrentDb.Name & ";"
For J = 1 To 10
  DB.Execute SQL1
  For I = 1 To 10
    DB.Execute SQL2
  Next I
  DB.Execute SQL3
  DB.Execute SQL4
Next J
Debug.Print "Execute (ADO): " & Timer - Z & " s"
Set DB = Nothing
End Function