Entwickler-Ecke
Datenbanken - Transaktions-Bestätigung bei AdoQuery
rob87 - Do 06.11.08 16:26
Titel: Transaktions-Bestätigung bei AdoQuery
Hallo zusammen,
ich hab grad mal ein kleines Problem.
Wenn ich mit einer ADOQuery-Komponente einen Delete mach, muss ich ja nach dem
Delphi-Quelltext
1: 2:
| Qry1.ExecSQL; Qry1.Transaction.Commit; |
auch irgendein CommitRetaining, etc. machen. Aber irgendwie find ich des grad ned. Commit, CommitRetaining, oder Transaction.Commit; gibts beim AdoQuery nicht??
Denn aktuell krieg ich bei einem erneuten Locate-"Versuch" folgende Meldung:
Die zum Aktualisieren angegebene Zeile wurde nicht gefunden. Einige Werte wurden seit dem letzten Lesen ggf. geändert"
alzaimar - Do 06.11.08 16:59
Eine Transaktion muss erstmal gestartet werden. Nach dem Ausführen der Befehle bestätigt man die Ausführung ('Commit') oder verwirft sie ('Rollback'). Mit ADO geht das in etwa so:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| ADOConnection.BeginTrans; Try ADOConnection.Commit; Except ADOConnection.Rollback; Raise End; |
So oder ähnlich.
rob87 - Do 06.11.08 17:13
alzaimar hat folgendes geschrieben : |
Eine Transaktion muss erstmal gestartet werden. Nach dem Ausführen der Befehle bestätigt man die Ausführung ('Commit') oder verwirft sie ('Rollback'). Mit ADO geht das in etwa so:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| ADOConnection.BeginTrans; Try ADOConnection.Commit; Except ADOConnection.Rollback; Raise End; |
So oder ähnlich. |
OK. Soweit die Theorie. So wollt ichs ja auch machen. Aber meine TADOQuery-Komponente kennt kein Commit oder Rollback ???
Ich hab mal ne Quellcode-Auszug:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| QryDel: TADOQuery; QryDel.SQL.Clear; QryDel.SQL.Text := 'delete from table1'; QryDel.ExecSQL;
|
alzaimar - Fr 07.11.08 09:32
rob87 hat folgendes geschrieben : |
..Aber meine TADOQuery-Komponente kennt kein Commit oder Rollback ???[delphi]
|
Aber die ADOConnection. Das ist ein eigenes Objekt der Klasse 'TADOConnection'. Bei meinen Projekten habe ich ein TDatamodule, in dem eine TADOConnection und diverse TADOQuery/TADODataset-Komponenten liegen. Alle sind dann mit der TADOConnection verbunden. Hier könntest Du auch eine Zugriffsteuerung (Login) verwenden (LoginPrompt-Eigenschaft).
alzaimar - Fr 07.11.08 10:39
Nein, aber es hätte sein können, das Du das Connection-Objekt nicht kennst.
rob87 - Fr 07.11.08 12:03
alzaimar hat folgendes geschrieben : |
| Nein, aber es hätte sein können, das Du das Connection-Objekt nicht kennst. |
Doch. doch.
Aber ich kenn halt von TIBQuery die Methoden Transaction.Commit; oder Transaction.CommitRetaining;
Und ich denk, dass ich des nach meinem TAdoQuery1.ExecSQL; auch brauch
alzaimar - Fr 07.11.08 12:08
rob87 hat folgendes geschrieben : |
| Und ich denk, dass ich des nach meinem TAdoQuery1.ExecSQL; auch brauch |
Nein, sondern mein Pattern.
alzaimar - Fr 07.11.08 13:06
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| ADOConnection.BeginTrans; Try DeineADOQuery.ExecSQL; ADOConnection.Commit; Except ADOConnection.Rollback; Raise End; |
rob87 - Fr 07.11.08 13:11
alzaimar hat folgendes geschrieben : |
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| ADOConnection.BeginTrans; Try DeineADOQuery.ExecSQL; ADOConnection.Commit; Except ADOConnection.Rollback; Raise End; | |
Hmmm... War gut gemeint. Gebracht hats nichts. :-( Es ist nach wie vor so, dass, wenn ich nach dem ExecSQL ein Locate machen will, mein Programm oben genannten Fehler bringt ;-)
alzaimar - Fr 07.11.08 13:19
Gut, das Eine hat mit dem Anderen ja nichts zu tun. Ich hatte die Fehlermeldung gar nicht beachtet, sondern nur Dein Bestreben, eine Transaktion ordendlich abzuwickeln (übrigens ist das bei einer einzigen Zeile, z.B. 'INSERT' oder 'UPDATE' nicht nötig)
Du machst also mit der ADOQuery ein 'DELETE' und versuchst an anderer Stelle dann, diesen Wert zu finden oder wie?
rob87 - Fr 07.11.08 13:53
alzaimar hat folgendes geschrieben : |
Gut, das Eine hat mit dem Anderen ja nichts zu tun. Ich hatte die Fehlermeldung gar nicht beachtet, sondern nur Dein Bestreben, eine Transaktion ordendlich abzuwickeln (übrigens ist das bei einer einzigen Zeile, z.B. 'INSERT' oder 'UPDATE' nicht nötig)
Du machst also mit der ADOQuery ein 'DELETE' und versuchst an anderer Stelle dann, diesen Wert zu finden oder wie? |
Ich mach ein Delete (eines Teilbereiches), und will irgendwann wieder auf die Tabelle zugreifen
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| if Locate( ) = false then insert; else edit; end; post; |
alzaimar - Fr 07.11.08 13:59
Und wo kommat das ExecSQL vor?
rob87 - Fr 07.11.08 14:31
alzaimar hat folgendes geschrieben : |
| Und wo kommat das ExecSQL vor? |
Des wird davor ausgeführt. Vor diesem Codeschnipsel
alzaimar - Fr 07.11.08 14:34
Ach so. Das Dataset, mit der Du das Locate/Edit/Post machst, weiss doch gar nicht, das Du etwas gelöscht hast. Das der Fehler beim Locate kommt, ist zwar merkwürdig (ich würde beim Post eine entsprechende Fehlermeldung erwarten), aber egal.
Wenn Du z.B. Edit... Post ausführst, wird eine UPDATE-Anweisung generiert und die zum Server geschickt. Normalerweise antwortet der mit 'Danke, ich habe 1 Zeile verändert'. Und ADO ist zufrieden, weil genau das erwartet wurde. Nun wird eine eben gelöschte Zeile per UPDATE verändert. Geht ja nicht, also schickt der Server 'Danke, ich habe 0 Zeilen verändert'. Und dann kommt dieser Fehler.
rob87 - Fr 07.11.08 14:50
alzaimar hat folgendes geschrieben : |
Ach so. Das Dataset, mit der Du das Locate/Edit/Post machst, weiss doch gar nicht, das Du etwas gelöscht hast. Das der Fehler beim Locate kommt, ist zwar merkwürdig (ich würde beim Post eine entsprechende Fehlermeldung erwarten), aber egal.
Wenn Du z.B. Edit... Post ausführst, wird eine UPDATE-Anweisung generiert und die zum Server geschickt. Normalerweise antwortet der mit 'Danke, ich habe 1 Zeile verändert'. Und ADO ist zufrieden, weil genau das erwartet wurde. Nun wird eine eben gelöschte Zeile per UPDATE verändert. Geht ja nicht, also schickt der Server 'Danke, ich habe 0 Zeilen verändert'. Und dann kommt dieser Fehler. |
Aber ich denk dass des bei mir trotzdem noch a bissal anders geregelt is.
Ich hab mehrere Daten in meiner Tabelle. Nun wird ein Teil gelöscht (meinetwegen alle mit dem Wert A im Attribut "Status"). Mittels ExecSQL. Später wird geschaut, ob für den status a schon werte da sind. wenn ja, werden diese überschrieben, wenn nicht eingefügt.
alzaimar - Fr 07.11.08 14:58
rob87 hat folgendes geschrieben : |
| Aber ich denk dass des bei mir trotzdem noch a bissal anders geregelt is. |
Wenn Du meinst.
Nochmal: Das Dataset, mit dem Du suchst, weiss doch gar nicht, das Du per ExecSQL (mit einer anderen Komponente) inzwischen Daten gelöscht hast.
rob87 hat folgendes geschrieben : |
| Ich hab mehrere Daten in meiner Tabelle. |
Definiere 'Tabelle'.
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| MyDataset.SQL.Text := 'select * from Tabelle'; MyDataset.Open;
AnotherQuery.SQL.Text := 'delete Tabelle'; AnotherQuery.ExecSQL;
|
alzaimar - Fr 07.11.08 15:47
Falsche Antwort auf die Preisfrage. Daher hat es noch nicht 'klick' gemacht.
Nach dem 'MyDataset.Open' wird der Inhalt der Tabelle in den Speicher deines PCs geladen. Danach löschst Du auf dem Server die Tabelle. Das 'MyDataset' weiss davon aber Nichts. Woher auch, das hat ihm ja noch niemand gesteckt.
Richtige Antwort: "Die gesamte Tabelle"
Anderes Beispiel:
2xPC (A und B)
A lädt die Tabelle.
B löscht sie.
A weiss davon nix und sieht die Tabelle immer noch auf dem Bildschirm.
Ob A und B zwei PCs oder nur zwei Objekte in deiner Anwendung sind, ändert nix.
Jetzt klar?
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!