ADODB: Connections und Connectionstrings

Möchtest Du den gesamten Artikel lesen? Und vielleicht sogar den Artikel im PDF-Format und die Beispieldateien herunterladen? Dann hole Dir den Artikel gleich hier - völlig kostenlos!

Wer auf die Inhalte von Datenbanken wie Access, SQL Server und anderen zugreifen möchte, benötigt eine spezielle Datenzugriffstechnologie. Unter VB6, VBA und twinBASIC verwendet man dazu in der Regel die DAO-Bibliothek, in Office “Microsoft Office 16.0 Access database engine Object Library” genannt, oder die ADODB-Bibliothek (“Microsoft ActiveX Data Objects 6.1 Library”). Geschichtlich wurde mal die eine, mal die andere von Microsoft als die zu bevorzugende Datenzugriffstechnik bezeichnet. Derzeit verwendet man meist DAO, vor allem in Verbindung mit Access-Datenbanken, aber beim Zugriff auf SQL Server-Datenbanken bietet ADODB einige Features, die wir mit DAO nicht nutzen können. In diesem Artikel steigen wir in die Programmierung von Datenbankzugriffen mit ADODB ein. Dabei schauen wir uns als Erstes die Connection-Klasse an, mit der erst einmal eine Verbindung zur Datenbank aufgebaut werden kann.

ADODB wurde mit der Version Access 2000 erstmalig eingeführt. Zuvor war DAO die meistverwendete Datenzugriffstechnik (Bibliothek Microsoft DAO 3.6 Object Library) in Zusammenhang mit dem Zugriff über die JET-Datenbank-Engine. Im Laufe der Jahre hat Microsoft jedoch entschieden, dass DAO wieder die wichtigste Technik für den Zugriff auf Datenbanken sein soll. Damit einher ging mit Access 2007 die Einführung einer neuen Variante der JET-Engine namens ACE (Access Database Engine) und damit eine neue Bibliothek mit dem Titel Microsoft Office 16.0 Access database engine Object Library.

Wie bereits erwähnt, gibt es jedoch einige Einsatzzwecke, bei denen ADODB Vorteile gegenüber DAO hat, weil es verschiedene Funktionen zur Verfügung stellt, die es in DAO nicht gibt. Dazu gehören die folgenden:

  • Bessere Unterstützung für SQL Server: ADODB ist für client-server-basierte Datenbanken wie SQL Server optimiert. DAO ist primär für Microsoft Access und Jet-Datenbanken konzipiert und weniger effizient bei der Arbeit mit SQL Server.
  • Unterstützung für OLE DB: ADODB verwendet OLE DB oder ODBC, um sich mit SQL Server zu verbinden, was eine performante und flexible Verbindung ermöglicht. DAO ist auf die Jet-Engine beschränkt, die für SQL Server nicht optimiert ist. Mit DAO können wir nur in direkt über Tabellenverknüpfungen oder Pass-Through-Abfragen auf SQL Server-Tabellen zugreifen.
  • Bessere Performance bei großen Datenmengen: ADODB kann große Datenmengen effizient über serverseitige Cursor oder Forward-Only-Recordsets abrufen. DAO lädt oft ganze Datensatzgruppen in den Speicher, was zu Performance-Problemen führt.
  • Mehr Flexibilität bei der Abfrageverarbeitung:ADODB erlaubt den direkten Aufruf von gespeicherten Prozeduren und somit parametrisierten Abfragen, was die Sicherheit und Performance erhöht. DAO unterstützt keine direkten Prozeduraufrufe in SQL Server.
  • Transaktionsunterstützung für SQL Server: ADODB bietet eine bessere Transaktionskontrolle mit BeginTrans, CommitTrans und RollbackTrans. DAO bietet zwar Transaktionsunterstützung, aber diese ist für Jet-Datenbanken optimiert und nicht für SQL Server.

Early oder Late binding

Wir können die Elemente der ADODB-Bibliothek auf verschiedene Arten nutzen – durch vorheriges Einbinden der Bibliothek (Early Binding) oder durch Deklarieren der Objektvariablen mit dem Datentyp Object und Einbinden zur Laufzeit (Late Binding).

Wir wollen wegen der damit verbundenen Vorteile zum Beispiel durch den Einsatz von IntelliSense hier mit Early Binding arbeiten.

Dazu benötigen wir einen Verweis auf die Bibliothek Microsoft ActiveX Data Objects 6.1 Library.

Diesen fügen wir wie in Bild 1 über den Verweise-Dialog hinzu.

Verweis auf die ADODB-Bibliothek

Bild 1: Verweis auf die ADODB-Bibliothek

Eigenschaften der Connection-Klasse

Die Connection-Klasse liefert die folgenden Eigenschaften, von denen wir uns die wichtigsten in den folgenden Abschnitten ansehen:

  • Attributes: Bestimmt oder setzt verschiedene Verbindungsattribute. Wird selten verwendet.
  • CommandTimeout: Legt fest, wie lange (in Sekunden) eine Abfrage auf eine Antwort warten soll, bevor ein Timeout-Fehler auftritt.
  • ConnectionString: Enthält die Verbindungsinformationen zur Datenbank (zum Beispiel Servername, Datenbankname, Benutzer, Passwort).
  • ConnectionTimeout: Gibt die maximale Zeit (in Sekunden) an, die beim Verbindungsaufbau auf eine Antwort gewartet wird, bevor ein Timeout-Fehler auftritt.
  • CursorLocation: Bestimmt, ob die Cursor-Verarbeitung clientseitig oder serverseitig erfolgt (adUseClient oder adUseServer).
  • DefaultDatabase: Gibt die Standard-Datenbank an, die nach dem Öffnen der Verbindung verwendet wird.
  • Errors: Liefert eine Sammlung von Fehlern, die während der letzten ADODB-Operation aufgetreten sind.
  • IsolationLevel: Gibt das Isolationsniveau für Transaktionen an (zum Beispiel ReadCommitted, Serializable).
  • Mode: Bestimmt die Art des Datenbankzugriffs (zum Beispiel Nur-Lesen, Schreibgeschützt, Exklusiv).
  • Properties: Eine Sammlung aller Eigenschaften des Connection-Objekts.
  • Provider: Gibt den verwendeten OLE DB-Provider an (zum Beispiel SQLOLEDB für SQL Server).
  • State: Gibt den aktuellen Status der Verbindung zurück (zum Beispiel adStateOpen oder adStateClosed).
  • Version: Gibt die Version von ADO zurück.

Methoden der Connection-Klasse

Außerdem bietet die Connection-Klasse die folgenden Methoden:

  • BeginTrans: Startet eine Transaktion, um mehrere Operationen als Einheit auszuführen.
  • Cancel: Bricht eine laufende Abfrage oder Operation ab.
  • Close: Schließt die Verbindung zur Datenbank.
  • CommitTrans: Bestätigt eine laufende Transaktion und speichert die Änderungen dauerhaft in der Datenbank.
  • Execute: Führt eine SQL-Abfrage aus und gibt ein Recordset oder die Anzahl der betroffenen Datensätze zurück.
  • Open: Stellt eine Verbindung zur Datenbank mit den angegebenen Verbindungsparametern her.
  • OpenSchema: Ruft Metadaten über die Datenbank ab (zum Beispiel Tabellen, Spalten, Indexe).
  • RollbackTrans: Bricht eine Transaktion ab und stellt die Daten vor der Transaktion wieder her.

Zugriff auf die aktuelle Access-Datenbank

Innerhalb von Access-Datenbanken liefert die ADODB-Bibliothek über die Eigenschaft Connection der Klasse CurrentProject ein Connection-Objekt für den Zugriff auf die aktuelle Datenbank.

Um diese zu nutzen, können wir direkt auf ihre Eigenschaften zugreifen – beispielsweise, indem wir die Verbindungszeichenfolge im Direktbereich ausgeben:

  CurrentProject.Connection.ConnectionString
Provider=Microsoft.ACE.OLEDB.12.0;User ID=Admin;Data Source=C:\...\ADODB_Connections.accdb;Mode=Share Deny None;Extended Properties="";Jet OLEDB:System database=C:\Users\User\AppData\Roaming\Microsoft\Access\System.mdw;Jet OLEDB:Registry Path=Software\Microsoft\Office\16.0\Access\Access Connectivity Engine;Jet OLEDB:Database Password="";Jet OLEDB:Engine Type=6;Jet OLEDB:Database Locking Mode=0;Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Global Bulk Transactions=1;Jet OLEDB:New Database Password="";Jet OLEDB:Create System Database=False;Jet OLEDB:Encrypt Database=False;Jet OLEDB:Don''t Copy Locale on Compact=False;Jet OLEDB:Compact Without Replica Repair=False;Jet OLEDB:SFP=False;Jet OLEDB:Support Complex Data=True;Jet OLEDB:Bypass UserInfo Validation=False;Jet OLEDB:Limited DB Caching=False;Jet OLEDB:Bypass ChoiceField Validation=False

Hier finden wir eine ganze Reihe Eigenschaften, die jedoch nicht alle immer benötigt werden.

Wir können die Verbindung auch direkt in Form einer Connection-Variablen speichern und darüber auf die enthaltenen Eigenschaften zugreifen:

Public Sub AktiveDatenbank()
     Dim cnn As ADODB.Connection
     Set cnn = CurrentProject.Connection
     Debug.Print cnn.ConnectionString
End Sub

Zu diesem Zeitpunkt haben wir übrigens noch keine Verbindung zur Datenbank hergestellt. Das Connection-Objekt kennt erst einmal nur die Verbindungszeichenfolge. Wie wir die Verbindung herstellen, schauen wir uns weiter unten an.

Verbindungszeichenfolgen für den Zugriff per ADODB

Dies war der stark vereinfachte Fall für den Zugriff auf die aktuelle Access-Datenbank. ADODB nutzt man jedoch in der Regel eher dazu, auf Datenquellen außerhalb der aktuellen Anwendung zuzugreifen. Wir schauen uns verschiedene Beispiele an, die oft verwendet werden.

Die Seite https://www.connectionstrings.com/ stellt immer aktuelle Informationen rund um die Verbindungszeichenfolgen für den Zugriff von System A auf Datenbank B bereitstellt.

Solltest Du einmal eine andere Datenquelle benötigen als die hier vorgestellten, findest Du dort alle denkbaren Konstellationen.

Hier siehst Du auch, dass Verbindungszeichenfolgen nicht immer so umfangreich sein müssen wie die soeben für CurrentProject.Connection ermittelte.

Verbindungszeichenfolge für SQL Server mit Windows-Authentifizierung

Wenn wir beispielsweise auf eine SQL Server-Datenbank zugreifen wollen, können wir grob Verbindungszeichenfolgen für die beiden Authentifizierungsarten Windows-Authentifizierung und SQL ServerAuthentifizierung zusammenstellen.

Die Verbindungszeichenfolge für die Windows-Authentifizierung sieht beispielsweise wie folgt aus – wobei wir als Servername amvDesktop2023 und als Datenbankname Mitarbeiterverwaltung verwendet haben:

Provider=MSOLEDBSQL;Server=amvDesktop2023;Database=Mitarbeiterverwaltung;Trusted_Connection=yes;

Verbindungszeichenfolge für SQL Server mit SQL Server-Authentifizierung

Die Verbindungszeichenfolge für die SQL Server-Authentifizierung sieht so aus. Hier verwenden wir statt dem Parameter Trusted_Connection=yes die beiden Parameter UID und PWD mit den jeweiligen Werten:

Provider=MSOLEDBSQL;Server=amvDesktop2023;Database=Mitarbeiterverwaltung;UID=[Benutzername];PWD=[Kennwort];

Verbindungszeichenfolge ohne Angabe der Datenbank

Wir können die beiden zuvor beschriebenen Verbindungszeichenfolgen auch ohne die Angabe einer Datenbank verwenden. Hier wird dann standardmäßig die master-Datenbank als Datenbank genutzt. Wir wir herausfinden können, welche Datenbank verwendet wird, zeigen wir weiter unten mit der Eigenschaft DefaultDatabase.

Verbindungszeichenfolge für Access-Datenbanken

Und wenn wir die Verbindungszeichenfolge für den Zugriff auf eine andere Access-Datenbank benötigen, stellen wir diese wie folgt zusammen – hier für eine Datenbank namens ADODB_Test.accdb:

Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\...\ADODB_Test.accdb;Persist Security Info=False;

Egal, ob wir eine reine Access-Connection erstellen oder eine für den SQL Server: Die angegebenen, teilweise nur aus vier Parametern bestehenden Verbindungszeichenfolgen werden nach dem Zuweisen automatisch um weitere Parameter ergänzt, die mit Standardwerten gefüllt werden.

Öffnen und Testen der Datenbankverbindung

Ob die Datenbankverbindung für die angegebene Verbindungszeichenfolge funktioniert, erfahren wir nur durch das Öffnen der Verbindung. Dazu nutzen wir die Open-Methode der Connection-Klasse.

Wenn wir dies in unser erstes Beispiel einbauen, in dem wir auf das Connection-Objekt der aktuellen Access-Datenbank zugreifen, sieht das wie folgt aus:

Dim cnn As ADODB.Connection
Set cnn = CurrentProject.Connection
cnn.Open

Wenn wir dies ausführen, erhalten wir allerdings die Fehlermeldung aus Bild 2. Warum ist das Objekt bereits geöffnet? Weil dieses direkt bei Start der Anwendung geöffnet und bereitgestellt wird. Wir können also direkt auf das Objekt zugreifen.

Fehler beim Versuch, eine geöffnete Verbindung erneut zu öffnen

Bild 2: Fehler beim Versuch, eine geöffnete Verbindung erneut zu öffnen

Prüfen, ob Verbindung bereits geöffnet ist

Wie können wir dann auf möglichst einfache Weise herausfinden, ob eine solche Verbindung bereits geöffnet ist oder nicht?

Dazu können wir die Eigenschaft State des Connection-Objekts nutzen.

Diese liefert einen der Werte der Enumeration ObjectStateEnum, die wie folgt lauten:

  • adStateClosed (0): Die Verbindung ist geschlossen.
  • adStateOpen (1): Die Verbindung ist erfolgreich geöffnet.
  • adStateConnecting (2): Die Verbindung wird gerade hergestellt.
  • adStateExecuting (4): Eine Abfrage wird gerade ausgeführt.
  • adStateFetching (8): Daten werden abgerufen.

Funktion zur lesbaren Ausgabe der Konstanten für ObjectStateEnum

Wir haben für die Enumeration ObjectStateEnum eine Funktion geschrieben, die uns für den Zahlenwert die jeweilige Konstante zurückgibt (siehe Listing 1).

Public Function ObjectStateEnum_String(lngObjectStateEnum As Long) As String
     Select Case lngObjectStateEnum
         Case 0
             ObjectStateEnum_String = "adStateClosed"
         Case 1
             ObjectStateEnum_String = "adStateOpen"
         Case 2
             ObjectStateEnum_String = "adStateConnecting"
         Case 4
             ObjectStateEnum_String = "adStateExecuting"
         Case 8
             ObjectStateEnum_String = "adStateFetching"
         Case Else
             ObjectStateEnum_String = "Unbekannter Status"
     End Select
End Function

Listing 1: Funktion zur lesbaren Ausgabe der Werte der Enumeration ObjectStateEnum

Diese erwartet den Zahlenwert der Eigenschaft State und liefert den Namen der jeweiligen Konstanten zurück. Damit können wir uns den Namen der Konstanten wie folgt ausgeben lassen:

Dim cnn As ADODB.Connection
Set cnn = CurrentProject.Connection
cnn.Open
Debug.Print ObjectStateEnum_String(cnn.State)

Connection immer wieder schließen

Bei Datenbankzugriffen ist es, wie auch bei allen anderen Objekten, die man im Laufe einer Session öffnet, wichtig, diese auch wieder zu schließen und den Speicherplatz freizugeben.

In den meisten Fällen machen sich Nachlässigkeiten hier zwar nicht bemerkbar, aber früher oder später treten dadurch vielleicht Probleme auf. Deshalb schließen wir eine von uns geöffnete Verbindung zunächst wie folgt:

cnn.Close

Anschließend leeren wir die Objektvariable:

Set cnn = Nothing

Unterschiede zwischen server- und clientseitigem Cursor in ADODB

Die CursorLocation-Eigenschaft im ADODB.Connection-Objekt legt fest, ob der Cursor auf dem Client oder auf dem Server verarbeitet wird.

Standardmäßig wird adUseServer (1) verwendet, wodurch Abfragen direkt auf dem SQL-Server ausgeführt werden. Dies reduziert die Last auf dem Client und ist effizient bei großen Datenmengen. Allerdings kann die Navigation durch Datensätze eingeschränkt sein, und eine stabile Netzwerkverbindung ist erforderlich.Alternativ kann adUseClient (2) gesetzt werden, wodurch die Abfrageergebnisse auf den Client-PC geladen werden. Dies ermöglicht eine vollständige Navigation durch die Daten (MoveFirst, MoveLast, MovePrevious), ist jedoch speicherintensiver.

Ein clientseitiger Cursor eignet sich besonders für Anwendungen mit vielen gleichzeitigen Benutzern oder wenn Daten offline bearbeitet werden sollen.

Diese Einstellung gilt generell für alle Zugriffe, die über diese Connection durchgeführt werden. Es gibt Recordset– und Command-Objekte für den Zugriff. Bei Recordsets können wir diese Eigenschaft allerdings noch individuell anpassen, Command-Objekte übernehmen diese Eigenschaft von der angegebenen Connection.

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