Visual Basic 6

Datenbankverbindung gekapselt

Auslagerung von Datenfunktionen in eine eigene Klasse

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
kick it on dotnet-kicks.de AddThis 0 wikio-Stimme(n) Trackback-Url...

Schlagworte

1 Kommentar bislang...

  • Hallo,

    erstmal funktioniert auch alles sehr gut.
    Leider habe ich ein Problem mit Gleitkommazahlen die ich aus Oracle nach VB nicht ohne Fehlermeldung bekomme.

    Hast Du da evtl. einen Tip zu den Returnvalues bzw. Datatypes??

    Gruß Daniel
    1
    Daniel Schröder : Montag, 21. Februar 2005 15:42

Dein Kommentar hierzu...


Kommentar-Feed für diesen Beitrag
Gravatare werden unterstützt .:. eMail-Adressen werden nicht veröffentlicht
 

RSS-Feed

Die URL des Standard-Newsfeed von zerbit.de lautet:

http://www.zerbit.de/rssfeed.aspx

Login


 

 

Statistik



kürzlich kommentiert

Artikel 5

  • Datum: 06.02.2005
    Kategorie: Visual Basic 6
    Zugriffe: 1.855
    Kommentare: 1
    Trackbacks: 0

Letzte Beiträge

Kategorien

Buttons & More

Blog-Roll

Banner Piraten-Partei