8.3 Datenbankzugriff mit Visual Basic 

Nach dem vorherigen Abschnitt wissen Sie, wie man eine Datenbank mit Tabellen und Beziehungen erstellt. In diesem Abschnitt wird Ihnen gezeigt, wie Sie mithilfe von Visual Basic auf eine Datenbank zugreifen.
8.3.1 Beispiel-Datenbank 

In diesem und den folgenden Abschnitten wird mit der Access-Datenbank firma.mdb gearbeitet. Diese Beispiel-Datenbank können Sie direkt vom beiliegenden Datenträger kopieren. Sie kann sowohl unter Access 2007 als auch unter älteren Versionen genutzt werden. Sie beinhaltet die Tabelle personen zur Aufnahme von Personendaten. Die Tabelle personen hat die Struktur wie in Abbildung 8.9 dargestellt.
Abbildung 8.9 Entwurf der Tabelle »personen«
Primärindex
Auf dem Feld personalnummer ist der Primärschlüssel definiert. Es kann also keine zwei Datensätze mit der gleichen Personalnummer geben. Es gibt bereits drei Datensätze mit den Inhalten, die in Abbildung 8.10 zu sehen sind.
Abbildung 8.10 Inhalt der Tabelle »personen«
8.3.2 Ablauf eines Zugriffs 

Der Zugriff auf eine Datenbank mit Visual Basic besteht aus folgenden Schritten:
- Verbindung aufnehmen zur Datenbank
- Absetzen eines SQL-Befehls an die Datenbank
- Auswerten des SQL-Befehls
- Verbindung zur Datenbank schließen
Diese Schritte werden nachfolgend zunächst erläutert und anschließend zusammenhängend in einem Visual Basic-Programm durchgeführt.
8.3.3 Verbindung 

OleDbConnection
Die Verbindung zu einer Access-Datenbank wird mithilfe eines Objekts der Klasse OleDbConnection aus dem Namespace OleDb aufgenommen. Ähnliche Klassen gibt es für die Verbindung zu anderen Datenbank-Typen bzw. zu Datenbank-Servern.
ConnectionString
Wichtigste Eigenschaft der Klasse OleDbConnection ist ConnectionString. Hier werden mehrere Eigenschaften für die Art der Verbindung vereinigt. Für Access sind dies:
- der Datenbank-Provider: Microsoft.Jet.OLEDB.4.0
- die Datenquelle (Data Source): hier ist dies C:\Temp\firma.mdb
Open(), Close()
Die Methoden Open() und Close() der Klasse OleDbConnection dienen zum Öffnen und Schließen der Verbindung. Eine offene Verbindung sollte so schnell wie möglich wieder geschlossen werden.
Microsoft Vista
Hinweis: Falls Sie auf einem PC mit dem Betriebssystem Microsoft Vista in der 64-Bit-Version entwickeln, dann können Probleme bei der Aufnahme der Verbindung zu einer Access Datenbank auftreten. Abhilfe dazu bekommen Sie in Abschnitt A.7.
8.3.4 SQL-Befehl 

Die Abkürzung SQL steht für Structured Query Language. SQL ist eine strukturierte Abfragesprache, also eine Sprache, mit deren Hilfe Datenbank-Abfragen ausgeführt werden können. Es gibt grundsätzlich zwei Typen von Abfragen:
select
- Auswahlabfragen zur Sichtung von Daten mit dem SQL-Befehl select
- Aktionsabfragen zur Veränderung von Daten mit den SQL-Befehlen update, delete, insert
Im weiteren Verlauf werden Grundlagen der Sprache SQL vermittelt, sodass einige typische Arbeiten mit Datenbanken durchgeführt werden können.
8.3.5 OleDb 

OleDb
Sie müssen den Namensraum OleDb mithilfe der Anweisung Imports System.Data.OleDb in jedem Projekt einbinden, in dem Sie auf eine Access-Datenbank zugreifen möchten.
SQL-Befehle werden zu einer Access-Datenbank mithilfe eines Objekts der Klasse OleDbCommand aus dem Namespace OleDb gesendet. Die beiden wichtigsten Eigenschaften dieser Klasse sind:
- Connection: Angabe der Verbindung, über die der SQL-Befehl gesendet wird
- CommandText: der Text des SQL-Befehls
Für die beiden verschiedenen Abfragetypen bietet die Klasse OleDbCommand die beiden folgenden Methoden:
ExecuteReader()
- ExecuteReader() dient dem Senden einer Auswahlabfrage und dem Empfangen des Abfrage-Ergebnisses.
- ExecuteNonQuery() dient dem Senden einer Aktionsabfrage und dem Empfangen einer Zahl. Dies ist die Anzahl der Datensätze, die von der Aktion betroffen waren.
OleDbReader
Das Ergebnis einer Auswahlabfrage wird in einem Objekt der Klasse OleDbReader aus dem Namespace OleDb gespeichert. In diesem Reader stehen alle Datensätze des Ergebnisses mit den Werten der angeforderten Felder.
8.3.6 Auswahlabfrage 

Als Beispiel für eine Auswahlabfrage nehmen wir den einfachsten Fall. Sie möchten alle Datensätze einer Tabelle mit allen Feldern sehen, siehe Abbildung 8.11.
Abbildung 8.11 Alle Datensätze sehen
Das Programm (im Projekt DBZugriffAccess):
Imports System.Data.OleDb Public Class Form1 Private Sub cmdAlleSehen_Click(...) Handles ... Dim con As New OleDbConnection Dim cmd As New OleDbCommand Dim reader As OleDbDataReader con.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source=C:\Temp\firma.mdb" cmd.Connection = con cmd.CommandText = "select * from personen" Try con.Open() reader = cmd.ExecuteReader() lstTab.Items.Clear() Do While reader.Read() lstTab.Items.Add( reader("name") & " # " & reader("vorname") & " # " & reader("personalnummer") & " # " & reader("gehalt") & " # " & reader("geburtstag")) Loop reader.Close() con.Close() Catch ex As Exception MessageBox.Show(ex.Message) End Try End Sub End Class
Listing 8.1 Projekt »DBZugriffAccess«, Auswahlabfrage
Zur Erläuterung:
- Es werden die beiden Objekte der Klassen OleDbConnection und OleDbCommand erzeugt.
- Es wird ein Verweis auf ein Objekt der Klasse OleDbReader erzeugt. Ein Verweis auf das Objekt selbst wird später von der Methode ExecuteReader() der Klasse OleDbCommand geliefert.
- Die Eigenschaft ConnectionString wird mit den Informationen für den Provider und die Datenquelle gefüllt.
- Es wird festgelegt, auf welcher Verbindung der SQL-Befehl gesendet wird.
SQL-Befehl
- Der SQL-Befehl select * from personen besteht aus den folgenden Elementen:
- select ... from ... : wähle Felder... von Tabelle ...
- *: eine Liste der gewünschten Felder im Abfrage-Ergebnis, * bedeutet alle Felder
- personen: Name der Tabelle, aus der ausgewählt wird.
Try...Catch
- Da es beim Zugriff auf eine Datenbank erfahrungsgemäß zahlreiche Fehlerquellen gibt, sollte er in einem Try...Catch-Block ablaufen. Ähnlich wie beim Zugriff auf eine Datei kann es vorkommen, dass die Datenbank gar nicht am genannten Ort existiert. Auch Fehler bei der SQL-Syntax werden an Visual Basic weitergemeldet. Die verschiedenen möglichen Fehlermeldungen helfen bei der Fehlerfindung.
- Mit Aufruf der Methode Open() wird die Verbindung geöffnet.
- Das Kommando wird mit der Methode ExecuteReader() gesendet. Es kommt ein Abfrage-Ergebnis von der Klasse OleDbReader zurück, dieses wird über den Verweis reader erreichbar gemacht.
- Da Sie nicht wissen, wie viele Datensätze das Abfrage-Ergebnis enthält, eignet sich zur Ausgabe ein Listenfeld. Dieses wird zuvor geleert.
Read()
- Die Methode Read() des Reader-Objekts liefert einen Datensatz und setzt einen sogenannten Datensatz-Zeiger auf den nächsten Datensatz. Falls kein weiterer Datensatz mehr da ist, also der Datensatz-Zeiger am Ende des Readers steht, wird False geliefert. Dies steuert die Do...Loop-Schleife.
- Innerhalb eines Datensatzes können die Werte der einzelnen Felder entweder über die Feldnummer oder den Feldnamen angesprochen werden. Hier wird die zweite, anschaulichere Möglichkeit verwendet. Es werden die Werte aller Felder ausgegeben, zur Verdeutlichung getrennt mit dem Zeichen #.
- Zu guter Letzt müssen noch der Reader und die Verbindung wieder geschlossen werden, jeweils mit Close().
Hinweis: Falls Sie auf eine Access 2007-Datenbank mit der Endung .accdb zugreifen, sieht der ConnectionString wie folgt aus:
con.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" & "Data Source=C:\Temp\firma.accdb;"
8.3.7 Aktionsabfrage 

Als Beispiel für eine Aktionsabfrage soll dienen: Alle Gehälter sollen um 5 % erhöht bzw. gesenkt werden, sodass anschließend die Liste z. B. wie folgt aussieht (siehe Abbildung 8.12).
Abbildung 8.12 Nach Erhöhung um 5 %
Das Programm (ebenfalls im Projekt DBZugriffAccess):
Public Class Form1 [...] Private Sub cmdErhöhen_Click(... ) Handles cmdErhöhen.Click, cmdSenken.Click Dim con As New OleDbConnection Dim cmd As New OleDbCommand Dim anzahl As Integer Dim op As String con.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source=C:\Temp\firma.mdb" cmd.Connection = con If ReferenceEquals(sender, cmdErhöhen) Then op = "*" Else op = "/" End If cmd.CommandText = "update personen set" & " gehalt = gehalt " & op & " 1.05" Try con.Open() anzahl = cmd.ExecuteNonQuery() MessageBox.Show( "Datensätze geändert: " & anzahl) con.Close() Catch ex As Exception MessageBox.Show(ex.Message) End Try End Sub End Class
Listing 8.2 Projekt »DBZugriffAccess«, Aktionsabfrage
Zur Erläuterung:
- Der Ablauf ist ähnlich wie bei einer Auswahlabfrage. Es wird allerdings kein Reader benötigt, da es bei Aktionsabfragen kein Abfrage-Ergebnis gibt, das ausgelesen werden könnte.
- Der SQL-Befehl für den Button Gehälter erhöhen lautet: update personen set gehalt = gehalt * 1.05. Er setzt sich zusammen aus:
- update ... set ... (aktualisiere Tabelle ... setze Werte ...)
- personen (Name der Tabelle, in der aktualisiert wird)
- gehalt = gehalt * 1.05 (eine oder mehrere Zuweisungen mit neuen Werten für ein oder mehrere Felder)
ExecuteNonQuery()
- Das Kommando wird mit der Methode ExecuteNonQuery() gesendet. Rückgabewert ist die Anzahl der Datensätze, die von der Aktionsabfrage betroffen waren. Diese werden angezeigt, siehe Abbildung 8.13.
ReferenceEquals()
- Die Gehälter werden erhöht bzw. gesenkt. Mithilfe der Methode ReferenceEquals() wird festgestellt, welcher der beiden Buttons betätigt wurde.
Abbildung 8.13 Anzahl der geänderten Datensätze