Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Firebird, TIBDataset Löschanweisungen unsichtbar (https://www.delphipraxis.net/126970-firebird-tibdataset-loeschanweisungen-unsichtbar.html)

alzaimar 5. Jan 2009 21:14

Datenbank: Firebird • Version: 2.x • Zugriff über: TIB-Komponenten

Firebird, TIBDataset Löschanweisungen unsichtbar
 
Hiho,

Ich erzeuge eine TIBDatabase, eine TIBTransaction und ein TIBDataset. Im TIBDataset steht sowas wie 'select * from Daten'.

Ich öffne das TIBDataset, lese alle Zeilen ein, merke mir die IDs, schließe das TIBDataset und dann baue ich mir aus den gemerkten IDs ein Delete-Statement zusammen:
Delphi-Quellcode:
const
  szDelete = 'Delete from %s where ID in (%s)';
var
  sData: string;
  sDeleteList: string;

begin
  fQuery.Dataset.Active := True; // fQuery ist ein privates Feld einer 'TFoobarQuery', die widerum das TIBDataset kapselt
  sDeleteList := '';
  try
    fQuery.Dataset.First;
    while not fQuery.Dataset.Eof do begin
      sDeleteList := sDeleteList + VarToStr (fQuery.Dataset['ID']) + ',';
      fQuery.Dataset.Next;
    end;
  finally
    fQuery.Dataset.Active := False;
    if sDeleteList <> '' then begin
      SetLength(sDeleteList, Length(sDeleteList) - 1);
      fConnection.Execute(Format(szDelete, [fTableName, sDeleteList])); // fConnection ist eine TFoobarConnection, die
    end;                                                               // eine TIBDatabase kapselt.
  end;
end;
...
procedure TConnection.Execute(const sSQL: string);
var
  cmd: TIBScript;

begin
  cmd := TIBScript.Create(nil);
  try
    fTransaction.StartTransaction;
    try
      cmd.Database := fDatabase;
      cmd.Script.Text := sSQL;
      cmd.ExecuteScript;
      fTransaction.Commit;
    except
      fTransaction.Rollback;
      raise;
    end;
  finally
    cmd.Free;
  end;
end;
Beim 1. Aufruf werden alle Zeilen eingelesen, das Delete-Statement gebastelt und alle Zeilen gelöscht. Toll.
Nun füge ich eine Zeile ein und rufe die o.g. Routine nochmal auf. Was soll ich sagen, das Dataset enthält die selben Daten, wie eben, obwohl die gelöscht sind (per IBExpert nachgeschaut).

Wie muss ich das anstellen, das so etwas Einfaches funktioniert, also das beim 2.Lesen mal zur Abwechslung andere Daten im Dateset stehen?

Danke und Grüße

ULIK 5. Jan 2009 21:25

Re: Firebird, TIBDataset Löschanweisungen unsichtbar
 
Kann das ein Problem mit den Transaktionen sein? Dein Dataset nutzt wohl eine andere Transaktion wie das Lösch-Statement. Wenn die Transaktion der Dataset nicht beendet wurde und der Isolation-Level auf RepeatableRead steht, dann sollten wohl immer die gleichen gleichen Daten gelesen werden. Hilt es hier, auf ReadCommited zu gehen bzw. die auch das Lesen in expliziten Transaktionen zu starten?
(Kann's momentan nicht testen, drum nur Vermutungen)

Grüße,
Uli

Sir Rufo 6. Jan 2009 00:27

Re: Firebird, TIBDataset Löschanweisungen unsichtbar
 
Es sieht wohl eher so aus, als ob die Daten noch im Cache gehalten werden.

Mit ReQuery müsste man eigentlich eine neue Abfrage erzwingen können.

alzaimar 6. Jan 2009 06:17

Re: Firebird, TIBDataset Löschanweisungen unsichtbar
 
ULIK: Dataset und Skript verwenden die gleiche Transaktion. Den Isolation Level kann ich nicht einstellen.
Sir Rufo: Wie führt man mit einem TIBDataset ein 'ReQuery' aus?

Bei IBExpert muss ich selbst SELECT-Anweisungen ('Data'-Tab in der Tabellenansicht) committen, um Änderungen sichtbar zu machen. Kann es sein, das das hier fehlt? Wieso muss man eigentlich SELECT-Anweisungen committen? :gruebel:

Blup 6. Jan 2009 08:24

Re: Firebird, TIBDataset Löschanweisungen unsichtbar
 
Zitat:

Zitat von alzaimar
ULIK: Dataset und Skript verwenden die gleiche Transaktion. Den Isolation Level kann ich nicht einstellen.
Sir Rufo: Wie führt man mit einem TIBDataset ein 'ReQuery' aus?

Bei IBExpert muss ich selbst SELECT-Anweisungen ('Data'-Tab in der Tabellenansicht) committen, um Änderungen sichtbar zu machen. Kann es sein, das das hier fehlt? Wieso muss man eigentlich SELECT-Anweisungen committen? :gruebel:

Offensichtlich verwendet das Script nicht die selbe Transaktion, wie man deinem Quelltext entnehmen kann.
Der Skriptkomponente wird keine Transaktion zugewiesen, damit erzeugt diese sich temporär eine eigene.

Auch das Lesen der Daten startet eine Datenbanktransaktion. So lange diese nicht abgeschlossen ist, wirst du innerhalb dieser Transaktion immer die Daten erhalten, die zum Zeitpunkt des Transaktionsstarts gültig waren oder innerhalb der Transaktion verändert wurden. Solange nur Daten gelesen werden, ist es egal ob mit Commit oder Rollback beendet wird.

Natürlich alles abhängig von der Art der Isolation...
http://de.wikipedia.org/wiki/Isolation_(Datenbank)

alzaimar 6. Jan 2009 09:40

Re: Firebird, TIBDataset Löschanweisungen unsichtbar
 
Hi Blup,

Danke für die Info: Ich kann das jetzt nicht testen (bin auf Arbeit), aber das könnte es wirklich sein (Skript/Transaktion).

Muss ich ein eigentlich ein 'SELECT' explizit mit einem 'StartTransaction/Commit' umschließen? Ich möchte solche Aktionen (SELECT, DELETE usw.) gerne vollständig kapseln und reentrant gestaltent, das also z.B. der Aufruf einer 'Select'-Methode nicht zu einem 'Transaktion ist noch offen' führt, was hier auch passiert ist.

Entschuldigt meine Unkenntnis, aber mit Firebird/TIBxxxx-Komponenten hab ich bisher nicht gearbeitet, sondern immer nur mit ADO, wo Transaktionen explizit angestoßen werden.

Hansa 6. Jan 2009 12:43

Re: Firebird, TIBDataset Löschanweisungen unsichtbar
 
@Alzaimar : in Deinem Alter sollte man sich mal so langsam mit Multi-Generationen-Architektur beschäftigen. :mrgreen: Damit man nicht wirklich jedes select umständlich mit StartTransaction-Commit/Rollback umschließen muss, gibts ja die Transaction-Isolation-Levels. Z.B. read_commited

mkinzler 6. Jan 2009 13:13

Re: Firebird, TIBDataset Löschanweisungen unsichtbar
 
Transaktionsisolation hat imho recht wenig mit MGA zu tun.

alzaimar 6. Jan 2009 19:08

Re: Firebird, TIBDataset Löschanweisungen unsichtbar
 
Hurra! Ich habe es geschafft! Ein Programm, das funktioniert!

Isolation Level eingestellt, dem Skript die gleiche Transaktion verpasst und :spin2:

Etwas schade allerdings, das eine so wichtige Eigenschaft wie 'Isolation Level' in der undokumentierten Params-Eigenschaft versteckt ist. Na ja, IB ist eben nur etwas für wahre Männer.

Danke für die sachliche Hilfe und das Verkneifen fieser Kommentare. :mrgreen: Mein besonderer Dank gilt dem einzig wahren FB/IB Guru: "Uns" Hansa :stupid: .

Sir Rufo 6. Jan 2009 19:19

Re: Firebird, TIBDataset Löschanweisungen unsichtbar
 
Zitat:

Zitat von alzaimar
Hurra! Ich habe es geschafft! Ein Programm, das funktioniert!

Isolation Level eingestellt, dem Skript die gleiche Transaktion verpasst und :spin2:

Etwas schade allerdings, das eine so wichtige Eigenschaft wie 'Isolation Level' in der undokumentierten Params-Eigenschaft versteckt ist. Na ja, IB ist eben nur etwas für wahre Männer.

Autotest Opel Corsa: hakelige Schaltung, schwere Kupplung => Fazit: scheiß Karre
Autotest Ferrari: hakelige Schaltung, schwere Kupplung => Fazit: geilste Karre von Welt

Zitat:

Zitat von alzaimar
Danke für die sachliche Hilfe und das Verkneifen fieser Kommentare. :mrgreen: Mein besonderer Dank gilt dem einzig wahren FB/IB Guru: "Uns" Hansa :stupid: .

"fiese Kommentare" ... wir ... NIEMALS ... :mrgreen:


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:00 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz