DBMS-unabhängiger Zugriff auf SQL Server und Co.

Lies diesen Artikel und viele weitere mit einem kostenlosen, einwöchigen Testzugang.

Haben Sie sich nicht auch schon immer gefragt, welche Zugriffstechnik am besten für den Zugriff auf Tabellen in aktiven Datenbanksystemen geeignet ist Falls Sie dies bereits mit ADODB- und DAO-Methoden getestet haben, wissen Sie vermutlich, dass keine Zugriffsmethode alle Wünsche eines Access-Programmierers erfüllt. Es bleibt also nichts anderes übrig, als die Einschränkungen hinzunehmen oder unterschiedliche Methoden parallel einzusetzen.

Im Beitrag Anmeldung an SQL Server und Co. wurde eine Methodensammlung zum Anmelden an aktive Datenbankmanagementsysteme (DBMS) vorgestellt (s. Shortlink 668). Diese Sammlung erweitern wir nun um eine Klassenstruktur zur Kapselung unterschiedlicher Verbindungstechniken. Voraussetzung zum Testen der nachfolgend vorgestellten Klassen ist eine Datenbank unter MySQL oder Microsoft SQL Server, die Sie über die Methoden des oben vorgestellten Beitrags mit der Frontend-Datenbank verknüpfen. Ist dies erledigt, können Sie mit den Methoden und Eigenschaften sehr viel einfacher auf die Datenbank zugreifen als zuvor – und noch besser: Wenn Sie sich entscheiden, die Backend-Datenbank vom SQL Server nach MySQL zu übertragen oder umgekehrt, brauchen Sie den Code für den Zugriff auf die Daten nicht zu ändern (das gilt wegen unterschiedlicher Dialekte jedoch nicht uneingeschränkt für die enthaltenen SQL-Anweisungen). Bevor wir hinter die Kulissen schauen, hier ein paar Beispiele. Das erste betrifft die Domänenfunktionen wie etwa DCount. Damit können Sie sich die Anzahl der Datensätze einer in der Datenbank enthaltenen oder verknüpften Tabelle wie folgt ausgeben lassen:

Debug.Print DCount("*€, "tblArtikel€)

Die nachfolgend vorgestellten Klassen ermöglichen erstens einen Zugriff auf die gleichen Informationen, allerdings auf Basis eines Recordsets. Handelt es sich um eine verknüpfte Tabelle, verwenden Sie einfach die folgende Anweisung:

Debug.Print CurrentDBConnection.DAO.DCount("*€, "tblArtikel€)

Vielleicht arbeiten Sie gar nicht mit einer Verknüpfung, sondern möchten per ADODB direkt auf die Tabelle des MySQL- oder SQL Servers zugreifen Dann funktioniert diese Variante:

Debug.Print CurrentDBConnection.ADODB.DCount("*€, "tblArtikel€)

Die Klassen bieten noch eine Reihe weiterer Funktionen, beispielsweise um ein Recordset zu erzeugen. Für eine verknüpfte Tabelle sieht dies so aus:

Set rst = CurrentDBConnection.DAO.OpenRecordset("SELECT * FROM tblArtikel€)

Ist die Tabelle nicht verknüpft, hilft die ADODB-Variante weiter:

Set rst = CurrentDBConnection.ADODB.OpenRecordset("SELECT * FROM tblArtikel€)

Sie können aber auch mit einem DAO-Recordset arbeiten, das via ODBC erzeugt wurde:

Set rst = CurrentDBConnection.ODBC.OpenRecordset("SELECT * FROM tblArtikel€)

Es gibt noch einige weitere Funktionen, mit denen Sie etwa den Connectionstring der aktuell verwendeten Verbindung ausgeben können. Mehr dazu erfahren Sie weiter unten.

Grundlagen

Für den Zugriff von einem Access-Frontend auf ein DBMS stehen unterschiedliche Verbindungstechniken zur Verfügung:

  • Verknüpfte Tabellen und Sichten (ODBC)
  • Pass-Through-Abfragen (ODBC)
  • ADO-Verbindung zur Datenbank (OLEDB)
  • ODBCDirect (ODBC)
  • DAO-Database-Instanz mit ODBC-Connectionstring (ODBC)

Die folgenden Abschnitte stellen diese Möglichkeiten und deren Vor- und Nachteile kurz vor.

Verknüpfte Tabellen und Sichten

Die Tabellen oder Sichten aus der Datenbank werden im Access-Frontend über ODBC verknüpft. Der Zugriff auf die Daten erfolgt über die lokale Frontend-Database-Instanz. Bei Abfragen mit verknüpften Tabellen wird die SQL-Anweisung von Jet beziehungsweise ACE (ab Access 2007) entgegengenommen und für die Weitergabe per ODBC an das Datenbanksystem aufbereitet.

Der ODBC-Manager übernimmt die aufbereitete SQL-Anweisungen und transferiert sie über den ODBC-Treiber an das DBMS. Das DBMS arbeitet die nun erhaltene SQL-Anweisung ab und gibt das Ergebnis an Jet zurück.

Sobald Jet- beziehungsweise VBA-Funktionen in der Abfrage eingesetzt werden, können diese nicht an das DBMS weitergereicht werden und müssen von Jet selbst abgearbeitet werden.

Tipp: Betrachten Sie die vom ODBC-Treiber für den SQL Server aufbereitete SQL-Anweisung und deren Abarbeitung mit dem SQL-Server-Profiler. Der Microsoft SQL Server übernimmt auch beim Einsatz von Access-Abfragen mit verknüpften Tabellen einen Großteil der Datenaufbereitung und nicht – wie oftmals behauptet wird – nur Access und Jet.

Zugriffsweg: Access  Jet/ACE  ODBC-Manager  ODBC-Treiber  DBMS

Vorteil: Vorgehensweise wie bei Access/Jet-Tabellen und somit wenig Umstellungsaufwand beim Wechsel von einer Jet-Datenbank zu einer Datenbank in einem aktiven DBMS.

Nachteil: Bei komplexeren Access-Abfragen auf verknüpfte Tabellen kann es zu Geschwindigkeitseinbußen kommen. Außerdem können die Fähigkeiten des DBMS nicht vollständig eingesetzt werden (etwa Einsatz von gespeicherten Prozeduren).

Pass-Through-Abfragen

Pass-Through-Abfragen erhalten über einen ODBC-Connectionstring eine Verbindung zum DBMS. Bei Pass-Through-Abfragen entfällt die Auswertung der SQL-Anweisung durch Jet. Daher muss die in einer Pass-Through-Abfrage enthaltene SQL-Anweisung im SQL-Dialekt des DBMS vorliegen.

Zugriffsweg: Access  ODBC-Manager  ODBC-Treiber  DBMS

Vorteil: Die SQL-Anweisung wird direkt ohne Umweg über Jet im DBMS ausgeführt. Dadurch können die Fähigkeiten des DBMS besser genutzt werden.

Nachteil: Die über eine Pass-Through-Abfrage erhaltenen Datensätze können nicht bearbeitet werden (bei einer verknüpften Sicht sind die Datensätze bearbeitbar, wenn im Access-Frontend ein Primärschlüssel eingestellt wurde).

ADO-Verbindung zur Datenbank

Der Zugriff erfolgt über einen OLEDB-Provider auf das DBMS. Beachten Sie, dass eine dezidierte Verbindung zum DBMS aufgebaut werden muss und nicht die ADODB-Connection des Frontends über CurrentProject.Connection und die verknüpften Tabellen genutzt wird. Denn sonst würde der Zugriff abermals über die ODBC-Verbindung laufen.

Damit die Verbindung direkt zum DBMS aufgebaut werden kann, müssen Sie eine ADODB-Connection mit dem OLEDB-Provider des DBMS öffnen. Für den Zugriff auf einen MSSQL-Server können beispielsweise die OLEDB-Provider “SQLOLEDB” oder “SQLNCLI” verwendet werden. Sollte für ein DBMS, wie bei MySQL, kein spezieller OLEDB-Provider vorhanden sein, können Sie als Brücke zwischen OLEDB und ODBC den Microsoft OLEDB-Provider für ODBC verwenden und für den Verbindungsaufbau den ODBC-Treiber des DBMS einsetzen. In diesem Fall wird zwar intern wieder über ODBC auf das DBMS zugegriffen, trotzdem können Sie die meisten Fähigkeiten der ADO-Bibliothek nutzen. Die in ADODB-Methoden eingesetzten SQL-Anweisungen werden über ADO an den OLEDB-Provider übergeben und von dort an das DBMS weitergereicht – ähnlich, wie bei den Pass-Through-Abfragen. Die SQL-Anweisungen müssen daher im jeweiligen SQL-Dialekt des DBMS verfasst werden.

Zugriffsweg: Access  ADO  OLEDB-Provider  DBMS

Vorteil: Für die meisten aktiven DBMS ist die ADO-Variante die schnellste Zugriffsmethode. Das ADODB-Objektmodell bietet außerdem umfangreichere Methoden für den Datenzugriff als das DAO-Objektmodell (zum Beispiel Ausführung von SQL-Anweisung über ADODB.Command).

Nachteil: Der Programmieraufwand der Standard-ADODB-Methoden ist höher als beim DAO-Zugriff. Datenverarbeitung über ADODB kann nur mit VBA oder Formulare genutzt werden. Der Einsatz für Access-Berichte ist in einer .mdb beziehungsweise .accdb nicht möglich (nur beim Einsatz eines ADP-Frontends erfolgt der Zugriff über ADODB/OLEDB).

ODBCDirect

Mit einem ODBC-Connectionstring wird ein DAO-Arbeitsbereich (DAO.Workspace) erstellt. Diese Zugriffsvariante stellt im Prinzip ein DAO-Gegenstück zur ADODB-Verbindung dar. Die SQL-Anweisungen erfolgen im SQL-Dialekt des DBMS.

Zugriffsweg: Access  ODBCDirect  ODBC-Manager  ODBC-Treiber  DBMS

Da diese Variante ab Access 2007 nicht mehr zur Verfügung steht, wird sie im folgenden Text nicht weiter berücksichtigt.

DAO-Database-Instanz mit ODBC-Connectionstring

Mithilfe eines ODBC-Connectionstrings wird eine DAO-Database-Instanz geöffnet. Die SQL-Anweisungen erfolgen im Access/Jet-SQL-Dialekt. Sie können diese Variante mit dem Vorgehen bei einem Jet-Backend vergleichen, bei dem nicht über verknüpfte Tabellen auf die Tabellen im Backend zugegriffen wird, sondern auf die Backend-Datenbank über eine eigene Database-Instanz.

Zugriffsweg: Access  Jet/ACE  ODBC-Manager  ODBC-Treiber  DBMS

Vorteil: Tabellen beziehungsweise Sichten müssen nicht verknüpft werden. Die Datensätze im geöffneten Recordset sind bearbeitbar, wenn die verwendete SQL-Anweisung eine Bearbeitung erlaubt.

Nachteil: Es können keine gespeicherten Prozeduren ausgeführt werden.

Zusammenfassung

Jede Verbindungstechnik hat in einem bestimmten Bereich Vorteile. Aus diesem Grund ist der Einsatz einer Kombination ausgewählter Techniken im Access-Frontend sinnvoll. Für MSSQL oder MySQL könnte etwa folgende Kombination eingesetzt werden:

  • Verknüpfte Tabellen/Sichten zur Datenbearbeitung in Formularen und als Datenbasis für Berichte (Sortierung und Filterung erfolgt über Access/Jet-SQL und wird per ODBC an das DBMS weitergereicht)
  • Pass-Through-Abfragen zur Datenanzeige in Formularen und als Datenbasis für Berichte (SQL-Anweisung kann per VBA angepasst werden)
  • ADO-Methoden für VBA-Zugriffe und ADO-Recordset als Datenbasis für Formulare und Steuerelemente. (Kombinations- und Listenfelder können in einer .mdb-Datei erst ab Access 2002 ein ADODB-Recordset als Datenbasis verwenden)

Vorteil: Die jeweils passende Technik ermöglicht effizienten Datenzugriff und Nutzung der Fähigkeiten des DBMS.

Nachteil: DAO- und ADO-Methoden müssen unterschiedlich programmiert werden. Das erschwert einen Wechsel der Zugriffstechnik.

Beispiel: Recordset öffnen

Das Öffnen eines DAO-Recordsets geschieht durch folgende Anweisungen:

Dim rst As DAO.Recordset
Set rst = CurrentDb.OpenRecordset("SELECT *
FROM Tabelle€, dbOpenDynaset, dbSeeChanges)

Die entsprechende Vorgehensweise für ein ADODB-Recordset benötigt diese Zeilen:

Dim rst As ADODB.Recordset
Set rst = New ADODB.Recordset
rst.Open "SELECT * FROM Tabelle€,
CurrentConnection, adOpenDynamic

Ziel dieses Beitrags

Der Zugriff auf ein DBMS soll standardisiert und DAO- und ADODB-Methoden sollen über eine ähnliche Schnittstelle aufrufbar werden.

Ausgangssituation und Konzept

Ein Access-Frontend wird für den Zugriff auf eine Datenbank in einem aktiven DBMS eingesetzt. Komplexere SQL-Anweisungen werden im DBMS in Form von Sichten und gespeicherten Prozeduren zur Verfügung gestellt. Aus diesem Grund ist der Einsatz von ADODB-Methoden beziehungsweise Pass-Through-Abfragen sinnvoll.

Anforderungen:

  • Unabhängig vom eingesetzten DBMS
  • Modularer Aufbau für flexiblen Einbau in Access-Anwendungen
  • DAO- und ADO-Methoden werden ähnlich aufgerufen.

Lösungsansatz:

  • DBMS-Verbindung wird über eine Schnittstelle zur DbConnectionInfo-Klasse aus dem Beitrag Anmeldung an SQL Server und Co. in Heft 3/2009 (s. Shortlink 668) eingestellt. Die Übergabe der Verbindungsparameter wird jedoch so gestaltet, dass die Zugriffsklassenstruktur auch ohne DbConnectionInfo-Klasse verwendbar ist.
  • Klassenmodule für ADODB (OLEDB), DAO (Jet) und DAO (ODBC) dienen zur Kapselung des Datenzugriffs.
  • Eine zusätzliche Klasse für die Ansteuerung der Zugriffstechniken erleichtert den Methodenaufruf.

Funktionsweise:

Über das Startformular frmAppWatcher wird die Startprozedur StartApplication aufgerufen. Diese Prozedur startet den Verbindungsaufbau und die Instanzierung der Klasse für die Zugriffssteuerung. Die Verbindungsparameter werden über die DbConnectionInfo-Instanz ausgelesen und der Zugriffssteuerung bei Bedarf bereitgestellt. Über die Klasse DbConnectionHandler steht ein Objektmodell zur Verfügung, dessen Elemente Sie bequem über die Punkt-Syntax ansprechen können – zum Beispiel CurrentDBConnection.ODBC.OpenRecordset(…).

Das Objektmodell stellt drei verschiedene Zugriffsvarianten zur Verfügung:

  • ADODB (Klasse AdodbHandler)
  • DAO (Klasse DaoHandler)
  • ODBC (Klasse OdbcHandler)

Zugriffsvariante ADODB

Diese Variante eignet sich für den direkten Zugriff auf die Datenbanken im DBMS. Sie bietet folgende Eigenschaften:

  • ConnectionString: OLEDB-Connectionstring für DBMS-Verbindung
  • CurrentConnection: ADODB-Connection zum DBMS

Außerdem können Sie folgende Methoden für die Ausführung von SQL-Anweisungen verwenden:

  • Execute: Execute-Methode zum Ausführen von SQL-Anweisungen. Syntax: Execute(CommandText, [RecordsAffected], [Options]) As ADODB.Recordset
  • InsertIdentityReturn: Methode zum Ausführen einer Insert-SQL-Anweisung auf eine Tabelle mit Rückgabe des Identity/Autowerts (IdentityTable kann für MSSQL verwendet werden). Syntax: InsertIdentityReturn(InsertSQL, [IdentityTable]) As Variant

Methoden zum Öffnen von Recordsets:

  • OpenRecordset: Funktioniert wie die herkömmliche OpenRecordset-Anweisung. Syntax: OpenRecordset(Source, [CursorType], [LockType], [CursorLocation]) As ADODB.Recordset
  • OpenRecordsetCommandParam: Öffnet ein ADODB-Recordset mittels ADODB-Command. Syntax: OpenRecordsetCommandParam(CmdText, CmdType, [commandParamDefs]) As ADODB.Recordset

Recordset-Ersatzfunktionen für Domänenfunktionen:

  • DLookup: Funktioniert wie die herkömmliche DLookup-Funktion. Syntax: DLookup(Expr As String, Domain, [Criteria]) As Variant
  • DLookupSQL: ähnlich DLookup – nur für direkte Übergabe einer SQL-Anweisung. Damit wird etwa unter ADODB der Einsatz einer gespeicherten Prozedur oder Funktion möglich. Syntax: DLookupSQL(sSQL, [index]) As Variant
  • DSum(Expr, Domain, [Criteria]) As Variant
  • DCount(Expr, Domain, [Criteria]) As Long
  • DMax (Expr, Domain, [Criteria]) As Variant
  • DMin (Expr, Domain, [Criteria]) As Variant

Zugriffsvariante DAO

Diese Variante ermöglicht den Zugriff über verknüpfte Tabellen beziehungsweise den Einsatz von CurrentDb des Frontends. Die Klasse bietet nur eine Eigenschaft:

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

Testzugang

eine Woche kostenlosen Zugriff auf diesen und mehr als 1.000 weitere Artikel

diesen und alle anderen Artikel mit dem Jahresabo

Schreibe einen Kommentar