Autor Beitrag
Nico B.
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 45

Win XP
Delphi 2006 Prof.
BeitragVerfasst: Do 24.06.10 14:21 
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.:
ausblenden 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;

//nun kann ich mir meine Abfrage-Ergebnisse anschauen

ADOConnection.Connected:=false;

//Kann ich mir jetzt immer noch meine Abfrage-Ergebnisse anschauen?


Ä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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 632
Erhaltene Danke: 121

Win 7 32-bit
Delphi 2006/XE
BeitragVerfasst: Do 24.06.10 16:10 
user profile iconNico B. hat folgendes geschrieben Zum zitierten Posting springen:
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.

ausblenden Delphi-Quelltext
1:
2:
3:
ADOConnection.Connected:=true;
ADOQuery.SQL.Clear;
ADOQuery.SQL.Append('SELECT * FROM Datenbank');

Es muß heißen "SELECT * FROM Datenbanktabelle".
ausblenden 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).
ausblenden Delphi-Quelltext
1:
//nun kann ich mir meine Abfrage-Ergebnisse anschauen					

Wie und wo? Ich sehe da nichts.
ausblenden Delphi-Quelltext
1:
2:
ADOConnection.Connected:=false;
//Kann ich mir jetzt immer noch meine Abfrage-Ergebnisse anschauen?

Nein, weil mit dem Schließen der Connection die Query-Komponente den Cursor auf die Ergebnismenge verliert.

Hier hast Du mal ein Abfragebeispiel:

ausblenden 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. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 45

Win XP
Delphi 2006 Prof.
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 632
Erhaltene Danke: 121

Win 7 32-bit
Delphi 2006/XE
BeitragVerfasst: Fr 25.06.10 07:41 
user profile iconNico B. hat folgendes geschrieben Zum zitierten Posting springen:

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:
ausblenden 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');
      // Es sind 593 Datensätze.
      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. Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 45

Win XP
Delphi 2006 Prof.
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1248
Erhaltene Danke: 187

XP - Server 2008R2
D2 - Delphi XE
BeitragVerfasst: 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