Fast jede Anwendung arbeitet mit Daten, die in einer externen Datenbank gespeichert
sind. Unter Visual Basic kommt man am besten und schnellsten an diese Daten,
wenn man Microsofts OLEDB- und ADO-Technik verwendet. Zu diesem Zweck muss man
zunächst über einen ConnectionString und einer ADO-Verbindungsinstanz die Verbindung
herstellen, bevor man z.B. über ein ADO-Recordset mit den Daten arbeiten kann.
Welche Datenbank im Hintergrund werkelt ist im Prinzip gleichgültig, solange
es dafür einen OLEDB-Provider (Treiber-DLL) gibt. Jede Datenbank geht jedoch
mit den gleichzeitigen Zugriffen auf die Daten etwas anders um. Hauptaugenmerk
liegt dabei auf den sog. Datenbank-Sessions, die jede Verbindung zugewiesen
bekommt. Allen Datenbanken haben jedoch eins gemeinsam: werden zu viele gleichzeitige
Verbindungen aufgebaut, werden sie zickig, da jede neue Session verwaltet werden
muss und dies unmittelbare Auswirkungen auf die Performance der Datenbank hat.
Aus diesem Grund sollte ein Entwickler mit diesen Verbindungen/Sessions sorgsam
umgehen, gerade wenn es sich um eine Anwendung handelt, mit der viele Benutzer
arbeiten. Es gibt wenig Fälle in denen es sinnvoll ist in einem Programm mehr
als eine Datenbankverbindung gleichzeitig zu öffnen. Weiterhin ist besser eine
Verbindung wieder zu schließen, nachdem man mit den Daten das angestellt hat,
was man anstellen wollte. Jetzt könnte man sagen, es sei das Beste beim Start
des Programms eine Datenverbindung zu öffnen und erst beim Schließen wieder
zu beenden. Falsch, denn zum einen setzen die meisten Datenbanken eine inaktive
Session nach ein paar Minuten zurück und man müsste dann zunächst immer erst
prüfen wie der Status der Verbindung ist und zum andern wäre es schlicht egoistisch
ein Verbindung auf "Halde" zu legen ohne sie zu verwenden.
Entschließt man sich nun die Verbindung dynamisch zu halten, macht es Sinn
eine zentrale Instanz (Schicht) zu entwickeln, die alle Aufgaben rund um den
Datenverkehr erledigt. Diesen Ansatz verfolgt die hier vorgestellte Daten-Klasse
clsData.
Die Datenklasse
Dreh und Angelpunkt der Klasse ist das private ADO-Verbindungsobjekt, dass
im Kopf der Klasse deklariert wird und von außen nicht abrufbar ist:
Private WithEvents pConn As ADODB.Connection
Danach folgt die Deklaration zweier Eigenschaften, die eventuell auftretende
Fehler innerhalb der Klasse nach außen weitereichen können, da die Klasse ja
lediglich als Vermittler zwischen den Anwendungsfunktionen und den Daten dienen
soll, und somit eine Fehlerbehandlung besser in der aufrufenden Methode stattfinden
sollte.
Um die Klasse nicht fix an eine einzige Datenbank zu binden, wird eine weitere
Eigenschaft deklariert, die den Connection-String aufnimmt und bei Ihrer Belegung
sofort die Funktion OpenConnection aufruft, die eine
Verbindung zur Datenbank aufbaut und in der globalen Variable
pConn speichert:
Private mvarErrorCode As Long
Private mvarErrorDesc As String
Private mstrConnString As String
'*** Eigenschaft ErrorDesc
Public Property Get ErrorDesc() As String
ErrorDesc = mvarErrorDesc
End Property
'*** Eigenschaft ErrorCode
Public Property Get ErrorCode() As Long
ErrorCode = mvarErrorCode
End Property
'*** Eigenschaft ConnString
Public Property Let ConnString(ByVal vData As String)
mstrConnString = CheckConnectionString(vData)
Call OpenConnection
End Property
Public Property Get ConnString() As String
ConnString = mstrConnString
End Property
'*** Funktion OpenConnection
Private Function OpenConnection()
On Error GoTo error_handler
'Connection öffnen, wenn Objekt leer
If pConn Is Nothing Then
Set pConn = New ADODB.Connection
pConn.CursorLocation = adUseClient
pConn.Open mstrConnString
End If
Exit Function
error_handler:
If Err <> 0 Then
mvarErrorCode = Err.Number
mvarErrorDesc = "Die Datenbankverbindung konnte nicht
hergestellt werden!" & _
vbCrLf & vbCrLf & "Fehler:" & vbCrLf
& Err.Description
End If
End Function
Die Datenbankverbindung soll automatisch wieder geschlossen werden, wenn
die Klasseninstanz terminiert wird:
Private Sub Class_Terminate()
Set pConn = Nothing
End Sub
Alle weiteren Datenfunktionen können nun implementiert werden:
Beispiel 1: ADO-Recordset als Rückgabewert an die aufrufende Funktion
Public Function GetContactData(ByRef rs As ADODB.Recordset)
Dim strSQL As String
Dim cm As ADODB.Command
On Error GoTo error_handler
'Sicherstellen, dass die Verbindung offen ist
Call OpenConnection
strSQL = "SELECT * FROM Contacts"
Set cm = New ADODB.Command
cm.CommandText = strSQL
cm.CommandType = adCmdUnknown
cm.ActiveConnection = pConn
Set rs = cm.Execute
If rs.AbsolutePosition = adPosUnknown Then
Set rs = Nothing
End If
error_handler:
mvarErrorCode = Err.Number
mvarErrorDesc = Err.Description
End Function
Beispiel 2: Datenlöschung mit Hilfe einer in der Datenbank gespeicherten
Prozedur
Public Function DeleteContact(ByVal lngContactID As Long) As
Boolean
Dim cm As ADODB.Command
Dim pmIn As ADODB.Parameter
Dim pmOut1 As ADODB.Parameter
Dim pmOut2 As ADODB.Parameter
On Error GoTo error_handler
'Sicherstellen, dass die Verbindung offen ist
Call OpenConnection
Set cm = New ADODB.Command
cm.ActiveConnection = pConn
cm.CommandType = adCmdStoredProc
cm.CommandText = "CONTACTS.delete_contact"
'Parameter (IN)
Set pmIn = cm.CreateParameter("nID", adNumeric, adParamInput)
cm.Parameters.Append pmIn
pmIn.Value = lngContactID
'Error-Parameter (OUT)
Set pmOut1 = cm.CreateParameter("vErrorCode", adNumeric, adParamOutput)
cm.Parameters.Append pmOut1
'Error-Parameter (OUT)
Set pmOut2 = cm.CreateParameter("vErrorMsg", adVarChar, adParamOutput,
1000)
cm.Parameters.Append pmOut2
cm.Execute
DeleteContact = True
error_handler:
mvarErrorDesc = CStr(Trim$(nz(pmOut2, "")))
mvarErrorCode = CLng(nz(pmOut1, 0))
Set pmIn = Nothing
Set pmOut1 = Nothing
Set pmOut2 = Nothing
Set cm = Nothing
End Function
Wie man sieht werden alle Fehler innerhalb der Datenfunktionen lediglich
an die dafür vorgesehenen Eigenschaften übergeben, um der aufrufenden Methode
die Möglichkeit zu geben sie abzurufen und auszuwerten. Der Aufruf sollte für
das Beispiel 2 wie folgt aussehen, wobei die Klasseninstanz
pcData in einem zentralen Bereich deklariert sein
muss:
...
'Datenverbindung aufbauen
Set pcData = New clsData
pcData.ConnString = pstrConnString
'Datenfunktion aufrufen
Call pcData.DeleteContact(lngContactID)
'Fehler auswerten
If pcData.ErrorCode <> 0 Then Err.Raise pcData.ErrorCode, , pcData.ErrorDesc
'Verbindung schließen
Set pcData = Nothing
...
Downloads
clsData.zip