Autor |
Beitrag |
rob87
      
Beiträge: 461
Win Me, Win XP Home, Win XP Prof
Delphi 2007 Enterprise
|
Verfasst: Di 02.12.08 10:47
Hallo,
ich habe ein DBGrid welches mir den Inhalt eines Querys anzeigt. Nun ist es so, wenn ich daraus den letzten Datensatz lösche bringt er mir ne unsaubere Meldung. Nun hab ich gedacht ich fang des so ab:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| if not QryShow.EoF then begin QryShow.Active := false; QryShow.Active := true; end else begin ShowMessage('Kein Datensatz vorhanden'); end; |
Aber mein Logik-Fehler ist nun, dass er dann auch jedesmal in den Else-Zweig geht, wenn ich bsw. den letzten Datensatz lösche. Denn ich sage auch in meiner Software, dass er nach dem Löschen zum nächsten DS springt.
Und nun such ich ne Möglichkeit, wie "if Query.Empty" oder sowas
|
|
delphiprogrammierer
      
Beiträge: 53
|
Verfasst: Di 02.12.08 11:32
Hmmm,
was hältst du davon, bevor du auf den nächsten Datensatz springst einfach zu schauen ob überhaupt noch ein nächster Datensatz existiert oder habe ich deine frage falsch interpretiert.
Delphiprogrammierer
|
|
rob87 
      
Beiträge: 461
Win Me, Win XP Home, Win XP Prof
Delphi 2007 Enterprise
|
Verfasst: Di 02.12.08 11:41
delphiprogrammierer hat folgendes geschrieben : | Hmmm,
was hältst du davon, bevor du auf den nächsten Datensatz springst einfach zu schauen ob überhaupt noch ein nächster Datensatz existiert oder habe ich deine frage falsch interpretiert.
Delphiprogrammierer |
Des is ja eben mein Problem. Wie fragt ma denn die Existenz ab? IF Query.EoF = true ?
|
|
zuma
      
Beiträge: 660
Erhaltene Danke: 21
Win XP, Win7, Win 8
D7 Enterprise, Delphi XE, Interbase (5 - XE)
|
Verfasst: Di 02.12.08 11:46
// nach 'unten' blättern wenn nicht dateiende
Delphi-Quelltext 1: 2:
| if not query.eof then query.next; |
// nach oben blättern, wenn nicht dateianfang
Delphi-Quelltext 1: 2:
| if not query.Bof then query.prior; |
aber:
wieso machst du das weiterscrollen manuell ??
einen DS löschen sollte doch automatisch auf den nächsten DS springen, falls vorhanden ?
_________________ Ich habe nichts gegen Fremde. Aber diese Fremden sind nicht von hier! (Methusalix)
Warum sich Sorgen ums Leben machen? Keiner überlebts!
|
|
rob87 
      
Beiträge: 461
Win Me, Win XP Home, Win XP Prof
Delphi 2007 Enterprise
|
Verfasst: Di 02.12.08 12:17
|
|
zuma
      
Beiträge: 660
Erhaltene Danke: 21
Win XP, Win7, Win 8
D7 Enterprise, Delphi XE, Interbase (5 - XE)
|
Verfasst: Di 02.12.08 12:31
nuja, würde ich anders lösen, aba egal.
du löscht also in der Datenbank, und liest dann neu
(man könnte auch gleichzeitig im QueryShow löschen und
sich das dauernde zu- und aufmachen sparen),
versuchst dann den gelöschten Datensatz wieder aufzurufen,
im normalfall landet er dann im Except, da der DS nicht mehr da sein sollte.
dort kannst du doch ganz einfach mit
Delphi-Quelltext 1: 2:
| if not queryshow.Bof and Queryshow.eof then queryshow.last; |
den letzten Datensatz aktivieren, sofern noch mind. ein DS da ist
_________________ Ich habe nichts gegen Fremde. Aber diese Fremden sind nicht von hier! (Methusalix)
Warum sich Sorgen ums Leben machen? Keiner überlebts!
|
|
rob87 
      
Beiträge: 461
Win Me, Win XP Home, Win XP Prof
Delphi 2007 Enterprise
|
Verfasst: Di 02.12.08 12:36
zuma hat folgendes geschrieben : | nuja, würde ich anders lösen, aba egal.
du löscht also in der Datenbank, und liest dann neu
(man könnte auch gleichzeitig im QueryShow löschen und
sich das dauernde zu- und aufmachen sparen) |
Und wie? Bin gern offen für Vorschläge
|
|
zuma
      
Beiträge: 660
Erhaltene Danke: 21
Win XP, Win7, Win 8
D7 Enterprise, Delphi XE, Interbase (5 - XE)
|
Verfasst: Di 02.12.08 13:53
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: 29: 30: 31: 32: 33: 34: 35: 36:
| procedure TIrgendwas.Datensatzlschen1Click(Sender: TObject); var merker : TBookmark; begin merker := QryShow.GetBookmark; if Qry1.Active then Qry1.Active := false;
Qry1.SQL.Clear; Qry1.SQL.Text := 'delete from ..... where ...'; try if not QryShow.Eof then begin Qry1.ExecSQL; QryShow.Delete; end else begin ShowMessage('Kein Datensatz vorhanden'); end; except on e : Exception do begin ShowMessage('Datensatz konnte nicht gelöscht werden'+char(13)+ char(13)+ 'Fehlermeldung: '+e.Message); end; end; try QryShow.GotoBookmark(merker); except QryShow.Last; end; DBGrid1.SetFocus; QryShow.FreeBookmark(merker);
end; |
kenn mich mit den ADO-Komponenten nicht aus, mach mehr mit IB-Komponenten.
Denke aber mal, das auch bei ADO der Query sowas wie 'autocommit' hat, damit wird der aktuelle Datensatz, wenn er im Query gelöscht wird, auch in der DB gelöscht, da der Query dann die auf ihm ausgeführten Operationen direkt in die DB überträgt (also auch insert, update, etc).
schon mal ausprobiert, einfach nur ein
Delphi-Quelltext
zu machen ?
_________________ Ich habe nichts gegen Fremde. Aber diese Fremden sind nicht von hier! (Methusalix)
Warum sich Sorgen ums Leben machen? Keiner überlebts!
|
|
Agawain
      
Beiträge: 460
win xp
D5, MySQL, devxpress
|
Verfasst: Di 02.12.08 14:02
hi
ich würd da mit record-count dran gehen.
Wenn 0 wird der Button gar nicht erst aktiviert.
Für das Löschen braucht man dann gar nix mehr. Die Frage ist aber, wieso da eine Delete where Bedingung ist.
Sollen denn einzelne Sätze durch Benutzereingriff gelöscht werden, oder direkt eine Serie von Datensätzen.
Die ganze Tabelle kannste mit SQL leeren und natürlich auch Teile davon.
Gruß
Aga
_________________ Gruß Aga
|
|
dummzeuch
      
Beiträge: 593
Erhaltene Danke: 5
Delphi 5 ent, Delphi 6 bis Delphi XE8 pro
|
Verfasst: Di 02.12.08 22:31
rob87 hat folgendes geschrieben : |
Und nun such ich ne Möglichkeit, wie "if Query.Empty" oder sowas |
Wenn ich mich recht erinnere:
Delphi-Quelltext
Apropos:
Kannst Du nicht statt die Query zu schliessen und zu oeffnen .Refresh aufrufen?
twm
|
|
rob87 
      
Beiträge: 461
Win Me, Win XP Home, Win XP Prof
Delphi 2007 Enterprise
|
Verfasst: Mi 03.12.08 09:07
zuma hat folgendes geschrieben : | 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: 29: 30: 31: 32: 33: 34: 35: 36:
| procedure TIrgendwas.Datensatzlschen1Click(Sender: TObject); var merker : TBookmark; begin merker := QryShow.GetBookmark; if Qry1.Active then Qry1.Active := false;
Qry1.SQL.Clear; Qry1.SQL.Text := 'delete from ..... where ...'; try if not QryShow.Eof then begin Qry1.ExecSQL; QryShow.Delete; end else begin ShowMessage('Kein Datensatz vorhanden'); end; except on e : Exception do begin ShowMessage('Datensatz konnte nicht gelöscht werden'+char(13)+ char(13)+ 'Fehlermeldung: '+e.Message); end; end; try QryShow.GotoBookmark(merker); except QryShow.Last; end; DBGrid1.SetFocus; QryShow.FreeBookmark(merker);
end; |
kenn mich mit den ADO-Komponenten nicht aus, mach mehr mit IB-Komponenten.
Denke aber mal, das auch bei ADO der Query sowas wie 'autocommit' hat, damit wird der aktuelle Datensatz, wenn er im Query gelöscht wird, auch in der DB gelöscht, da der Query dann die auf ihm ausgeführten Operationen direkt in die DB überträgt (also auch insert, update, etc).
schon mal ausprobiert, einfach nur ein
Delphi-Quelltext
zu machen ? |
Aber des versteh ich no ned ganz:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| Qry1.SQL.Clear; Qry1.SQL.Text := 'delete from ... where ... '; try if not QryShow.Eof then begin Qry1.ExecSQL; QryShow.Delete; end else begin ShowMessage('Kein Datensatz vorhanden'); end; except on e : Exception do begin ShowMessage('Datensatz konnte nicht gelöscht werden'+char(13)+ char(13)+ 'Fehlermeldung: '+e.Message); end; end; |
Warum sagst du nun ExecSQL (enthält einen Delete-Befehl)
und zusätzlich QryShow.Delete;
Wenn ich deinen Code ausführe und den letzten DS in meinem DBGrid löschen will, springt er bei mir in den Catch-Block und schreibt: Nicht genügend Schlüsselinformationen zum Aktualisieren
|
|
zuma
      
Beiträge: 660
Erhaltene Danke: 21
Win XP, Win7, Win 8
D7 Enterprise, Delphi XE, Interbase (5 - XE)
|
Verfasst: Mi 03.12.08 09:49
_________________ Ich habe nichts gegen Fremde. Aber diese Fremden sind nicht von hier! (Methusalix)
Warum sich Sorgen ums Leben machen? Keiner überlebts!
|
|
rob87 
      
Beiträge: 461
Win Me, Win XP Home, Win XP Prof
Delphi 2007 Enterprise
|
Verfasst: Mi 03.12.08 10:02
zuma hat folgendes geschrieben : | Delphi-Quelltext 1:
| Qry1.SQL.Text := 'delete from ..... where ...'; |
Delphi-Quelltext 1: 2: 3: 4: 5:
| try if not QryShow.Eof then begin Qry1.ExecSQL; QryShow.Delete; |
du hast da ja 2 Query's, einen zum Anzeigen, einen zum 'arbeiten'. Und beide arbeiten mit derselben Datenmenge, das ist meistens heikel, die dann zu synchronisieren. wie sieht denn der lesebefehl für die Query's aus ?
normalerweise würde ja ein Query reichen, warum du 2 nutzt, kann ich nur vermuten
versuch mal, deinen source so umzubauen, das du nur noch einen query nutzt. |
Ja, du hast Recht. Das ist nur der Löschbefehl und noch nicht die eigentliche Löschung...
Ich habe zwei Querys. Einen zum Anzeigen und den anderen zur Löschung. Ein temporärer Query sozusagen.
Der Grund, war es, dass Ganze übersichtlich zu halten. Aber ich darf die zwei Querys nicht zusammenfassen. Es müssen zwei bleiben...
Aber mit zwei muss es ja genauso funktionieren. Ich mach ein Select, und dann kann ich mit nem anderen Query mir gewisse fokusierte Datensätze löschen, bearbeiten, etc...
Warum sollte mein ExecSQL und anschlißend ein Tabellen schließen und wieder öffnen nciht funktionieren?? Ist vll. etwas umständlicher, aber es funktioniert. (und ist meinesachtens auch übersichtlicher)
|
|
zuma
      
Beiträge: 660
Erhaltene Danke: 21
Win XP, Win7, Win 8
D7 Enterprise, Delphi XE, Interbase (5 - XE)
|
Verfasst: Mi 03.12.08 10:44
oberste Coderregel: was funzt, ist richtig
aber ob deine herangehensweise übersichtlicher oder performanter ist, lässt sich vortrefflich drüber streiten.
Das es 2 Query's bleiben müssen, möchte ich auch mal stark bezweifeln, aber ist ja deine Entscheidung.
Klar, kannst du (auf kosten der Performance) immer wieder Query's auf- und zumachen, gehen wird das. Daß das übersichtlicher ist, bestreite ich aber definitiv.
Ein Query = eine mögliche Fehlerquelle,
2 Query's = 2 Fehlerquellen + 'Wechselwirkungsfehlerquelle' = hoch x Fehlerquellen ...
Ich denke mal, deine 2er-Lösung rührt daher, das du im Umgang mit den Querys und dem Zusammenspiel zwischen Anzeige und Datenzugriff noch nicht so sicher bist.
_________________ Ich habe nichts gegen Fremde. Aber diese Fremden sind nicht von hier! (Methusalix)
Warum sich Sorgen ums Leben machen? Keiner überlebts!
|
|
rob87 
      
Beiträge: 461
Win Me, Win XP Home, Win XP Prof
Delphi 2007 Enterprise
|
Verfasst: Mi 03.12.08 10:48
zuma hat folgendes geschrieben : |
aber ob deine herangehensweise übersichtlicher oder performanter ist, lässt sich vortrefflich drüber streiten.
|
Mit Sicherheit nicht performanter
zuma hat folgendes geschrieben : |
Das es 2 Query's bleiben müssen, möchte ich auch mal stark bezweifeln, aber ist ja deine Entscheidung. |
Nicht ganz. Firmensache!
zuma hat folgendes geschrieben : |
Klar, kannst du (auf kosten der Performance) immer wieder Query's auf- und zumachen, gehen wird das. Daß das übersichtlicher ist, bestreite ich aber definitiv.
Ein Query = eine mögliche Fehlerquelle,
2 Query's = 2 Fehlerquellen + 'Wechselwirkungsfehlerquelle' = hoch x Fehlerquellen ...
|
Auch klar.
zuma hat folgendes geschrieben : |
Ich denke mal, deine 2er-Lösung rührt daher, das du im Umgang mit den Querys und dem Zusammenspiel zwischen Anzeige und Datenzugriff noch nicht so sicher bist. |
Jein.
Und was mach ma nun? Hät da mal ne Verständnisfrage: Ich lass meine Daten über ein Query in einem DBGrid anzeigen. Soweit so gut. Wenn ich nun ein Delete-SQL auf den einen DS ausführe, löscht er diesen in der DB. Soweit klar.
Zweiter Schritt ist die Aktualisierung des DBGrids. Und da gibts ja nun verschiedene Möglichkeiten:
- Im Anzeige-Query auch den DS löschen
- Anzeige-Query refreshen (keine Ahnung, warum des bei mir ned reicht, dass ers aktualisiert)
- Anzeige.Query beenden und neu aufmachen (die softwaretechnisch umständlichste Art) Und mit genau dieser Art muss ichs lösen. Und da happerts bei mir momentan noch...
Zuletzt bearbeitet von rob87 am Mi 03.12.08 10:52, insgesamt 1-mal bearbeitet
|
|
zuma
      
Beiträge: 660
Erhaltene Danke: 21
Win XP, Win7, Win 8
D7 Enterprise, Delphi XE, Interbase (5 - XE)
|
Verfasst: Mi 03.12.08 10:52
_________________ Ich habe nichts gegen Fremde. Aber diese Fremden sind nicht von hier! (Methusalix)
Warum sich Sorgen ums Leben machen? Keiner überlebts!
|
|
rob87 
      
Beiträge: 461
Win Me, Win XP Home, Win XP Prof
Delphi 2007 Enterprise
|
Verfasst: Mi 03.12.08 10:57
Logik-Vorschlag (dass ist die Programmlogik sowieso sie momentan realisiert ist)
- QryDelete zusammenbauen
- Wenn QryShow nicht leer ist => QryDelete ausführen + Anzeige aktualisieren
Oder hast du nen anderen Vorschlag? Natürlich könnte man das "QryDelete zusammenbauen" noch in die IF-Abfrage mit reinnehmen. Wär logisch.
Passt!! So funktionierts:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| try if not QryShow.IsEmpty then begin Qry1.SQL.Clear; Qry1.SQL.Text := 'delete from rufbereitschaft01 '+ ' where Jahr = '+IntToStr(QryShow.FieldByName('Jahr').Value)+' '+ ' and KW = '+IntToStr(QryShow.FieldByName('KW').Value)+' '; Qry1.ExecSQL; QryShow.Active := false; QryShow.Active := true; end else begin ShowMessage('Kein Datensatz vorhanden'); end; except on e : Exception do begin ShowMessage('Datensatz konnte nicht gelöscht werden'+char(13)+ char(13)+ 'Fehlermeldung: '+e.Message); end; end; |
|
|
zuma
      
Beiträge: 660
Erhaltene Danke: 21
Win XP, Win7, Win 8
D7 Enterprise, Delphi XE, Interbase (5 - XE)
|
Verfasst: Mi 03.12.08 11:30
wenns funktioniert: siehe oberste Coderregel weiteroben
Bedenken hätte ich, wenn das Prog von mehreren gleichzeitig genutzt wird.
dann zeigt evtl. das eine prog nen DS an, den ein anderer User bereits in DB gelöscht hat.
das löschen klappt dann nicht mehr, da der ds nicht mehr da ist. aber da execsql nix zurückliefert, kriegt man den Fehler eh nich mit und sachlich ists egal, da er ja eh gelöscht werden sollte. dann hat lediglich einer 'überflüssig gearbeit' (=löschen geklickt).
_________________ Ich habe nichts gegen Fremde. Aber diese Fremden sind nicht von hier! (Methusalix)
Warum sich Sorgen ums Leben machen? Keiner überlebts!
|
|
rob87 
      
Beiträge: 461
Win Me, Win XP Home, Win XP Prof
Delphi 2007 Enterprise
|
Verfasst: Mi 03.12.08 11:42
|
|
|