title image


Smiley Anmerkung: (viel Text geworden)
Du definierst die Connection Lokal in einer Sub oder Function (Vermutung meinerseits)

Dim cnnDB As ADODB.Connection



Delhalb darfst du die am Ende der Sub nicht schließen:

'cnnDB.Close 'darf hier nicht geschlossen werden, da sonst datagrid wieder leer ist!

wie du ja richtig festgestellt hast.



Das ist aber nicht "die feine englische ..."

Du hast immer noch eine offene Connection zur Datenbank aber du hast keine Möglichkeit mehr, darauf zuzugreifen (weil's ja dein Connection-Objekt nicht mehr gibt).

Wenn jetzt diese Sub erneut aufgerufen wird, erstellst du eine neue Connection zur Datenbank mit dem gleichen Resultat.

Diese so erstellten und nicht geschlossenen Connections werden erst beim Programmende von VB geschlossen (wenn du Glück hast).



Besser ist es, eine Connection modal (mit Private in einer Form etc) oder lokal (mit Public in einem Modul) zu definieren und immer die gleiche Connection zu verwenden.

Diese Vorgehensweise ist zum einen performancemäßig besser weil du nur eine Conneciton hast, außerdem hast du damit weniger Update-Probleme.

ADO arbeitet Updatebefehle intern asynchron ab, es kann also sein, daß eine Connection noch nicht in der DB gespeichert hat, wenn eine andere Connection diese Daten aus der DB liest.



Wenn du zB zwei Connections zur DB hast und in der ersten Connection Daten änderst und speicherst, hast du die neuen Daten in der gleichen Connection sofort zur Verfügung. Diese Änderungen sind aber deshalb noch lange nicht in der DB!

Die zweite Connection weiß nichts von der ersten, wenn du dann eine Abfrage mit der zweiten Connection machst, kann es sein, daß du noch die alten Daten bekommst, weil diese zweite Connection aus ihrem Cache liest (bzw von der DB) nicht aus dem Cache der ersten Connection (in der die Änderungen sind)





Im Prinzip hast du zwei Möglichkeiten, diese Problematik zu umgehen:

1. Wie bereits gesagt, nur eine Connection pro Programm und Datenbank verwenden, die im ganzen Programm verwendet wird. (in mindestens 90% der Fälle reicht eine Connection)

2. Die Recordsets mit adLockBatchOptimistic öffnen. (nur bei CursorLocation = adUseClient)



Den ersten Fall habe ich bereits geschildert, besonders interessant ist aber die zweite Möglichkeit.

Wenn man einen Recordset mit adLockBatchOptimistic öffnet, kann man jederzeit die Verbindung zur Datenbank kappen (also die Connection schließen).

Man kann auch bei einem geöffneten Recordset die ActiveConnection-Eigenschaft auf Nothing setzen und das Connection-Objekt sterben lassen.

In diesem Fall kannst du also den cnnDB.Close jederzeit aufrufen, die Daten beiben da.

Man muß aber nicht die Connection trennen, die darf genauso weiterbestehen und gesetzt sein.



Man kann trotzdem im Recordset beliebig Änderungen vornehmen und mit Update speichern. Diese Änderungen sind allerdings nur in diesem Recordset, sonst nirgens.

Selbst ein anderer Recordset der gleichen Quelle und Connection weiß davon nichts.

Um diese Änderungen in der DB zu speichern, muß man eine Connection zur DB erstellen, der ActiveConnection-Eigenschaft zuweisen und die UpdateBatch-Methode aufrufen.

Erst dann sind die Änderungen in der DB.

Alternativ dazu gibt es die Methode CancelBatch, die nicht speichert, sonder den veränderten Recordset wieder in den vorherigen Zustand versetzt.

Das ist im Prinzip eine Undo-Funktion.





In der Praxis verwende ich oft die Kombination aus beiden oben genannten Möglichkeiten.



Ein Programm verwendet genau eine Connection zur Datenbank. Völlig egal, von woher ein Recordset beim Open die Daten bekommt (aus dem Cache der Connection oder von der DB), man hat immer die aktuellen Daten.

Wenn man einen Dialog hat, in dem die Daten verändert werden können, bietet sich die Batch-Technik an. Normalerweise ruft man ja einen solchen Dialog modal auf, damit der User diesen Dialog zuerst schließen muß, wenn der was anderes machen will.

Solche Dialoge haben idR einen OK-Button und einen Abbrechen-Button. Beim OK-Button müssen die Änderungen gespeichert werden, beim Abbrechen-Button muß der Zustand wiederhergestellt werden, der vor dem Aufruf des Dialogs vorhanden war.



Wenn man den entsprechenden Recordset mit adLockBatchOptimistic öffnet, braucht man nur im QueryUnload-Event prüfen, ob der OK-Button geklickt wurde.

Dazu muß man nur in der Form eine boolsche Variable deklarieren, die beim OK-Button auf True gesetzt wird.

Wurde der OK-Button gedrückt, ruft man UpdateBatch auf, ansonsten ruft man CancelBatch auf.

Somit braucht man sich überhaupt nicht darum kümmern, was der User ändert. Wenn der Dialog nicht mit OK beendet wird, ist alles wieder so wie vorher (ohne daß man sich selbst die Ursprungswerte merken muß), ansonsten sind die neuen Werte enthalten (den "normalen" Update pro Datensatz braucht man natürlich trotzem).

Nach so einem Dialog braucht man dann den (von Lordchen) gesagten Refresh-Befehl für alle geöffneten Recordsets, die die gleichen Basis haben (theoretisch nur beim OK-Button, schadet aber in den anderen Fällen auch nicht).



Bsp:

Option Explicit



Private MbooOK As Boolean



Private Sub cmdCancel_Click()

   Unload Me

End Sub



Private Sub cmdOK_Click()

   MbooOK = True

   Unload Me

End Sub



Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)

   If MbooOK Then

      '// UpdateBatch aufrufen

   Else

      '// CancelBatch aufrufen

   End If

End Sub





Anm: Nicht alle möglichen Kombinationen aus Connection.CursorLocation, Recordset.CursorType und Recordset.LockType werden von jedem Datenbanksystem unterstützt.

Man bekommt zwar beim Open immer eine gültigen Recordset, aber diese drei Eigenschaften werden uU automatisch geändert.

Am besten nach dem Open diese drei Eigenschaften überprüfen (Recordest ins Überwachungsfenset), damit man feststellen kann was man bekommen hat.


Gruß
Gaga

___________________________________________________________________

Profilösungen für VB6
wenn nicht anders angegeben, sind alle Codebeispiele nicht getestet, nur getippt


geschrieben von

Login

E-Mail:
  

Passwort:
  

Beitrag anfügen

Symbol:
 
 
 
 
 
 
 
 
 
 
 
 
 

Überschrift: