SQL ausführen mit Execute statt DoCmd.RunSQL

In unseren Audits mit unseren Kunden und Lesern untersuchen wir auch regelmäßig den VBA-Code in deren Access-Anwendungen. Dabei fallen uns immer wieder Programmiergewohnheiten auf, die irgendwann einmal eingeführt und seitdem nie wieder geändert wurden. Eine davon ist, SQL-Anweisungen wie INSERT INTO, UPDATE oder DELETE mit der Methode RunSQL der DoCmd-Klasse auszuführen. Das ist grundsätzlich nicht falsch, solange dies zum Ziel führt. Es gibt jedoch noch mindestens eine Alternative, insbesondere den Aufruf mit der Execute-Methode der Database-Klasse. Diese führt zwar auch nur die übergebene Aktionsabfrage aus, aber sie bietet dennoch einige Vorteile gegenüber DoCmd.RunSQL. Welche das sind und wie wir überhaupt die DoCmd.RunSQL-Methode durch die Execute-Methode ersetzen können, zeigen wir in diesem Beitrag.

RunSQL und Execute einsetzen

Grundsätzlich sind die beiden Methoden ähnlich und dienen dem Aufruf von Aktionsabfragen zum Löschen, Anlegen oder Bearbeiten von Datensätzen einer Tabelle. Als Beispiel verwenden wir eine Tabelle namens tblKategorien mit den beiden Feldern KategorieID (Primärschlüsselfeld) und Kategorie (Textfeld mit eindeutigem Index).

Wenn wir einen Eintrag zu einer Tabelle hinzufügen wollen, erledigen wir das mit RunSQL wie folgt (in einer Zeile im Direktbereich eingeben):

DoCmd.RunSQL "INSERT INTO tblKategorien(Kategorie)  VALUES(''Kategorie 1'')"

Bei der Execute-Methode können wir direkt mit CurrentDb arbeiten und übergeben die gleiche Abfrage:

CurrentDb.Execute "INSERT INTO tblKategorien(Kategorie)  VALUES(''Kategorie 1'')"

Es bietet sich jedoch an, direkt eine Variable für das Database-Objekt zu deklarieren. Das ist auch Voraussetzung für das Nutzen der weiteren Vorteile der Execute-Methode:

Public Sub Beispiel_Execute()
     Dim db As DAO.Database
     Set db = CurrentDb
     db.Execute "INSERT INTO tblKategorien(Kategorie)  VALUES(''Kategorie 2'')"
End Sub

Warum wird RunSQL überhaupt verwendet?

Einer der Gründe, warum sich die RunSQL-Methode der DoCmd-Klasse so großer Beliebtheit erfreut, ist vermutlich in der technischen Nähe der DoCmd-Methoden zu den Aktionen in den Access-Makros zu finden.

Access-Makros waren einer der Gründe, warum auch Nicht-Programmierer mit Access schnell Ergebnisse erzielen können: Man braucht nicht VBA zu beherrschen, sondern kann schnell im Makro-Editor ein paar Befehle zusammenstellen, die beispielsweise durch den Klick auf eine Schaltfläche ausgeführt werden.

Die Befehle des Makro-Editors finden wir zum größten Teil in den Methoden der DoCmd-Klasse.

Wer also in seiner Anfangszeit in Makros die Methode AusführenSQL genutzt hat, und dann zur Nutzung von VBA übergegangen ist, wird logischerweise zu der entsprechenden DoCmd-Methode RunSQL gegriffen haben, um das gleiche Ergebnis zu erzielen.

Die Makro-Aktion AusführenSQL ist übrigens mindestens seit Access 2010 nicht mehr verfügbar – wir mussten ein altes Access 97-Buch heranziehen, um sicherzugehen, dass es diese Makro-Aktion einmal gab.

Und da die RunSQL-Methode nach wie vor funktioniert, gab es für viele Entwickler keinen Grund, sich nach einer Alternative umzusehen.

Diese stellen wir in diesem Beitrag mit der Execute-Methode der Database-Klasse vor und zeigen auch, warum dies die bessere Variante ist. Dafür sprechen die folgenden Gründe:

  • Wir können Fehler bei Verwendung von Execute über eine benutzerdefinierte Fehlerbehandlung abfangen. Bei DoCmd.RunSQL gelingt dies nicht.
  • Wir können nach dem Ausführen der Execute-Methode direkt ermitteln, wie viele Datensätze von der Aktionsabfrage betroffen sind.
  • Und wir können beim Hinzufügen eines Datensatzes mit INSERT INTO direkt die ID des Autowertfeldes des hinzugefügten Datensatzes ermitteln.
  • Wenn wir mehrere Aktionsabfragen in einer Transaktion ausführen wollen, ist dies nur mit der Execute-Methode möglich.

Fehlerbehandlung beim RunSQL vs. Execute

Wenn wir eine SQL-Anweisung mit RunSQL ausführen, können wir bestimmte Fehler nicht mit einer benutzerdefinierten Fehlerbehandlung erkennen.

Grundsätzlich werden bei Verwendung von RunSQL ohne weitere Maßnahmen alle Fehler über die Benutzeroberfläche gemeldet, zum Beispiel, wenn wir einen Datensatz anfügen wollen und damit einen bereits vorhandenen Wert in einem eindeutigen Feld hinzufügen würden:

Public Sub Beispiel_RunSQL_Fehler()
     DoCmd.RunSQL "INSERT INTO tblKategorien(Kategorie)  VALUES(''Kategorie 1'')"
End Sub

Dieser Fehler würde uns nur über die Benutzeroberfläche gemeldet werden (siehe Bild 1).

Datenfehler beim DoCmd.RunSQL

Bild 1: Datenfehler beim DoCmd.RunSQL

Wir können diesen Fehler nicht über eine Fehlerbehandlung etwa mit On Error Resume Next abfangen und auch die Fehlernummer anschließend nicht mit Debug.Print Err.Number auswerten.

Wir können lediglich die Anzeige der Fehlermeldung unterbinden, indem wir zuvor die Anweisung DoCmd.SetWarnings False einstellen und diese anschließend mit DoCmd.SetWarnings True wieder aktivieren. In diesem Fall würden wir den Fehler jedoch gar nicht bemerken.

Andere Fehler, wie Tippfehler in Tabellen- oder Feldnamen, können wir hingegen mit einer benutzerdefinierten Fehlerbehandlung abfangen:

On Error Resume Next
DoCmd.RunSQL "INSERT INTO tblKategorien(Kategoriename) VALUES(''Kategorie 1'')"
Debug.Print Err.Number, Err.Description

Bei Verwendung der Execute-Methode können wir alle Fehler mit einer benutzerdefinierten Fehlerbehandlung abfangen. Hier sind allerdings nicht alle Fehler standardmäßig überhaupt erkennbar:

  • Fehler etwa durch Tippfehler in Tabellen- oder Feldnamen lösen immer einen Fehler aus, den man behandeln kann.
  • Fehler durch Verletzung von Restriktionen wie beim Anlegen eines bereits vorhandenen Wertes in einem Feld mit eindeutigem Index werden standardmäßig nicht abgefangen!

Dies löst einen Fehler aus, wenn das Feld Kategoriename nicht existiert:

db.Execute "INSERT INTO tblKategorien(Kategoriename)  VALUES(''Kategorie 2'')"

Diese Anweisung hingegen löst keinen Fehler aus, auch wenn Kategorie 1 bereits in einem anderen Datensatz vorhanden ist:


Nur für Abonnenten

Ab hier wird’s wirklich spannend – der Rest ist exklusiv für Abonnenten.

Mit dem Abo von Access im Unternehmen bekommst du den kompletten Artikel – inklusive vollständigem Code, Beispieldatenbank und Schritt-für-Schritt-Erklärung.

So sparst du dir stundenlanges Herumprobieren, vermeidest teure Fehler in deiner Access-Anwendung und kannst Lösungen direkt in deinem Unternehmen einsetzen, statt nur darüber zu lesen.

Teste Access im Unternehmen jetzt 4 Wochen lang kostenlos: Voller Zugriff auf alle Artikel, Downloads und Beispieldatenbanken. Kein Risiko – wenn es für dich nicht passt, kündigst du einfach innerhalb der ersten vier Wochen.

Bereits Abonnent? Hier einloggen


Kostenlos & unverbindlich

Oder hast Du eine konkrete Frage zu Deiner eigenen Access-Anwendung?

Vielleicht stellt Deine Anwendung Dich vor eine Herausforderung, zu der Du bisher keine Lösung findest. Schlechte Performance, kein ausreichender Zugriffsschutz, Du bist unsicher über Dein Datenmodell oder Dein Code liefert unerklärliche Fehler?

In unserem kostenlosen Access-Audit schaut sich André Minhorst persönlich gemeinsam mit Dir Deine Lösung per Zoom an – und zeigt Dir, wo Datenmodell, VBA-Code, Ergonomie und Sicherheit Optimierungspotenzial bieten.

Jetzt kostenloses Access-Audit anfordern →

Schreibe einen Kommentar