Entwickler-Ecke
Datenbanken - Ergebnis einer Abfrage nach Schließen der Connection halten
Nico B. - Do 24.06.10 14:21
Titel: Ergebnis einer Abfrage nach Schließen der Connection halten
Hallo Leute,
ich hab mal ne Frage.
Ich frage eine DB über ADOQuery's ab.
Was passiert, wenn ich die ADOConnection nach einer Abfrage schließe?
Bsp.:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| ADOConnection.Connected:=true; ADOQuery.SQL.Clear; ADOQuery.SQL.Append('SELECT * FROM Datenbank'); ADOQuery.ExecSQL; ADOQuery.Open;
ADOConnection.Connected:=false;
|
Ändern kann ich nichts. Das ist klar.
Aber kann ich noch in der Ergebnisliste von Zeile zu Zeile springen und die Ergebnisse verarbeiten?
Gerd Kayser - Do 24.06.10 16:10
Nico B. hat folgendes geschrieben : |
| Was passiert, wenn ich die ADOConnection nach einer Abfrage schließe? |
Dann verlierst Du den Cursor auf die Ergebnismenge. Die bis dahin ausgewerteten Datensätze sind verarbeitet, der Rest nicht.
Delphi-Quelltext
1: 2: 3:
| ADOConnection.Connected:=true; ADOQuery.SQL.Clear; ADOQuery.SQL.Append('SELECT * FROM Datenbank'); |
Es muß heißen "SELECT * FROM Datenbanktabelle".
Delphi-Quelltext
1: 2:
| ADOQuery.ExecSQL; ADOQuery.Open; |
Das sind verschiedene Paar Schuhe. ExecSQL wird bei Inserts, Deletes und Updates verwendet. Open nur bei Abfragen (also reinen Selects).
Wie und wo? Ich sehe da nichts.
Delphi-Quelltext
1: 2:
| ADOConnection.Connected:=false; |
Nein, weil mit dem Schließen der Connection die Query-Komponente den Cursor auf die Ergebnismenge verliert.
Hier hast Du mal ein Abfragebeispiel:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| DatenModul.IBQuery1.SQL.Clear; DatenModul.IBQuery1.SQL.Add('select distinct Monat from TabKalender '); DatenModul.IBQuery1.SQL.Add('where '); DatenModul.IBQuery1.SQL.Add(' (TSYSDP2A = TSYSDP2B); '); DatenModul.IBQuery1.Open; while not DatenModul.IBQuery1.Eof do begin Monat := DatenModul.IBQuery1.FieldByName('Monat').AsInteger;
if Monat > 0 then for Schleife := 0 to DMonatsauswahl.ComponentCount - 1 do if (Components[Schleife] is TLMDSpeedButton) and (TLMDSpeedButton(Components[Schleife]).Tag = Monat) then begin TLMDSpeedButton(Components[Schleife]).Enabled := true; TLMDSpeedButton(Components[Schleife]).Color := clMoneyGreen; end;
DatenModul.IBQuery1.Next; end; DatenModul.IBQuery1.Close; |
Nico B. - Fr 25.06.10 07:30
Hallo Gerd,
na klar "SELECT * FROM Datenbanktabelle".
Danke für die Info zum ExecSQL und Open... Das hab ich dann bisher immer falsch gemacht.
Nun noch mal zu deinem Beispiel:
Deine While-Schleife würde also nicht funktionieren, wenn ich davor die Connection der Query löse?
Gerd Kayser - Fr 25.06.10 07:41
Nico B. hat folgendes geschrieben : |
Deine While-Schleife würde also nicht funktionieren, wenn ich davor die Connection der Query löse? |
Ein kleines Beispiel, wie man das testen kann:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28:
| procedure TForm1.Button1Click(Sender: TObject); var Zaehler : integer; Anzahl : integer; begin Zaehler := 0; IBDatabase1.Connected:= true; with IBQuery1 do begin SQL.Clear; SQL.Add('select * from TabPlatten'); Open; Last; First; Anzahl := RecordCount; Label1.Caption := 'Datensätze vorhanden: ' + IntToStr(Anzahl); while not Eof do begin Inc(Zaehler); Label2.Caption := 'Datensätze verarbeitet: ' + IntToStr(Zaehler); if Zaehler = 100 then IBDatabase1.Connected:= false; Next; end; Close; end; end; |
Mit Last und First wird bei einem bidirektionalem Cursor die Ergebnismenge komplett geholt. Query hat also hier 593 Datensätze am Wickel. In der Schleife wird beim 100. Datensatz die Verbindung gekappt. Als Folge davon wird die Exception "Operation bei geschlossener Datenmenge nicht ausführbar" geworfen und die Schleife abgebrochen. Die Zählervariable hat dann den Wert 100. Das heißt, 100 Datensätze wurden verarbeitet, aber 493 Datensätze sind verworfen worden, weil IBQuery den Cursor auf die Ergebnismenge verliert.
Nico B. - Fr 25.06.10 08:50
Mhm, Mist.
Gibt es denn eine Möglichkeit die Datensätze zügig irgendwohin zu übertragen, wo ich auf sie zugreifen kann ohne das die Connection bestehen bleiben muss?
Denn mein Problem ist folgendes:
Ich mache eine Abfrage in einer Datenbank X und will dann die Ergebnisse schrittweise mit den Einträgen in einer Datenbank Y vergleichen. Ich möchte jedoch nicht während der gesamten Zeit die Verbindung zur Datenbank X offen halten.
Richtig cool wäre also eine Art Offline-ADOQuery, die die Ergebnisse der Online-ADOQuery einfach übertragen bekommt.
bummi - Fr 25.06.10 08:55
Wenn Du bei Deinem Adodataset den Locktype auf ltBatchOptimistic setzt, kannst Du mit den Daten auch arbeiten nachdem Du die Connection auf nil gesetzt hast.
Lesend, mit IB habe ich keine Erfahrungen funtioniert zuverlässig mit Access und MS SQL-Server
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!