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:

Ende des frei verfügbaren Teil. Wenn Du mehr lesen möchtest, hole Dir ...

den kompletten Artikel im PDF-Format mit Beispieldatenbank

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar