![]() |
Datenbank: MS SQL • Version: 2000 • Zugriff über: ADO
Ein Datensatz wird ausgewählt, mehrere geändert, warum?
Moin Zusammen,
um bei einem Datensatz den Status zu aktualisieren verwende ich folgenden Aufruf:
Delphi-Quellcode:
Der Wert in FsTripID ist die Caption einer Listview-Zeile, und enthält eine ID, ausserdem ist [id] der Primärschlüssel der Tabelle.
rsWork := TADODataSet.Create(nil);
try rsWork.ParamCheck := false; rsWork.Connection := DM.conTravelDB; sQuery := 'SELECT [completed],[storniert] FROM [traveltrip_SAP] WHERE [id]=' + FsTripID; if not DoQuery(sQuery,rsWork) then Exit; try rsWork.Edit; rsWork.FieldValues['completed'] := BooleanToField(true); rsWork.FieldValues['storniert'] := BooleanToField(false); rsWork.Post; finally rsWork.Close; end; finally FreeAndNil(rsWork); end; Sobald diese Routine aufgerufen wird, werden (angeblich) manchmal mehrere Sätze geändert. Betroffen sind Sätze, bei denen das Feld [completed] ungleich NULL ist (kann dann noch 1 oder 0 sein), das Feld [storniert], und ein weiteres Feld gleich 0 oder gleich NULL sind. Noch eine Erklärung zu dem "angeblich": Bei zwei verschiedenen Personen auf zwei verschiedenen Rechnern soll dies aufgetreten sein, auf meinem Rechner kann ich das leider nicht reproduzieren. Allerdings habe ich auch keinen Grund anzunehmen, dass es bei den Betroffenen nicht wie beschrieben passiert ist. Hat jemand irgendeine Idee, was an der obigen Routine diesen Fehler verursachen kann? |
Re: Ein Datensatz wird ausgewählt, mehrere geändert, warum?
Die Routine scheint ok zu sein. Es liegt eher die Vermutung nahe, dass sie mehrfach aufgerufen wird...
|
Re: Ein Datensatz wird ausgewählt, mehrere geändert, warum?
Moin Union,
danke für die Info. So hatte ich das leider auch gesehen ;-) Die Funktion wird aber über einen Menüpunkt des Kontextmenüs des Listviews aufgerufen, so dass der mehrfache Aufruf eher nicht zu erwarten ist, ausser man wählt den Menüpunkt mehrfach aus. |
Re: Ein Datensatz wird ausgewählt, mehrere geändert, warum?
Du könntest dies ja durch Sperren des Menupunktes währrend des Updates verhindern.
|
Re: Ein Datensatz wird ausgewählt, mehrere geändert, warum?
Moin mkinzler,
danke für den Tip. So etwas in der Art baue ich auch gerade ein. (sobald die Gefahr besteht, dass innerhalb einer Ereignisroutine eine andere aufgerufen wird, werden pauschal alle deaktviert, und nach der Routine wieder aktiviert. Das habe ich in allen Programmteilen drin gehabt, nur nicht in diesem :? ;-)) |
Re: Ein Datensatz wird ausgewählt, mehrere geändert, warum?
Hallo,
mir scheint die Routine so korrekt zu sein. Eventuell fragst Du mal vor dem Finally den Wert von RowsAffected ab, hier sollte stehen, wieviele Sätze betroffen wurden. Ist RowsAffected <> 1, ist irgendwas schiefgegangen. Versuche dann einfach das Ergebnis des SQL's satzweise in eine Textdatei zu schreiben und Dir diese als Fehlerhinweis zukommen zu lassen oder wieauchimmer die Fehler weitergegeben werden. Vielleicht kannst Du aber auch vor dem "edit" mal RecordCount abfragen, ist der <> 1 wurde zuviel oder zu wenig gefunden und dann die Ergebnismenge in einer für Dich verwertbarer Form ausgeben. Wahrscheinlich sind in der Datenbank irgendwelche Daten etwas anders als erwartet. Oder könnte es in extremen Fällen passieren, dass FsTripID leer ist? Appropopopo: Was passiert, wenn FsTripID einen Wert einhält, den es in der Datenbank nicht (mehr) gibt? Können die Benutzer die Daten gleichzeitig ändern, ist die ID änderbar? Nach meiner Erfahrung stehen RowsAffected und RecordCount nicht bei allen Datenbanken zur Verfügung, so dass der Wert 0 für eines oder beide Attribute nicht unbedingt ein Fehler sein muss. Hier hilft leider nur Try and Error. Der Ansatz mit dem Deaktivieren ist auch nicht verkehrt, hab' da mal ein Programm gehabt, bei dem es eine Anwenderin schaffte, sich quasi permanent selbst zu überholen, sie hat die Daten derart schnell erfasst und diverse andere Teile des Programmes bedient, so dass man an der Oberfläche sehen konnte, wie die ganze Aktuallisiererei hinterher hinkte. Stephan |
Re: Ein Datensatz wird ausgewählt, mehrere geändert, warum?
Moin Stephan,
die ID ist der Primärschlüssel, der als Identity deklariert ist. Das der Wert leer ist kann nicht passieren, da für den Fall, dass keine Zeile des ListView ausgewählt wurde (Selected = nil) die Funktion nicht ausgeführt wird. Die Idee mit dem RecordCount könnte ich auch noch mal umsetzen, allerdings dürfte es auch bei mehreren zurückerhaltenen Sätzen nicht zu einem Problem kommen, da ja, wenn überhaupt, nur der erste Satz geändert werden würde. Da allerdings über Gleichheit des PK die zu ändernden Daten abgefragt werden, ist es eigentlich nicht möglich eine Anzahl > 1 zu erhalten. Zitat:
Zitat:
Zitat:
Zitat:
Der MS-SQL liefert das AFAIK zurück, so dass ich dass jetzt auch noch an allen in Frage kommenden Stellen mal einbauen werden. Ist der Wert <> 1 schreibe ich mir ein wenig in meine Logdatei. |
Re: Ein Datensatz wird ausgewählt, mehrere geändert, warum?
Hallo,
Zitat:
Wenn da intern (von wem in der/den Datenbankschnittstelle/n auch immer) ein Update ala where id = FsTripID abgesetzt wird, tritt nämlich genau der Effekt auf, der Dich hier gerade zum Grübeln bringt. Stephan |
Re: Ein Datensatz wird ausgewählt, mehrere geändert, warum?
Moin Stephan,
Zitat:
Kannst Du bitte mal deutlicher erklären was Du meinst, denn offensichtlich hat die Kombination Edit/Ändern/Post ja eben nicht den Effekt wie ein Update where [id] = FsTripID, sollte ihn aber haben? BTW: Ich war sowieso schon dabei die Statusänderungen (es sind vier ähnlich aufgebaute Routinen) auf ADOCommand und SQL-String mit UPDATE umzubauen, nur wiederstrebt es mir ein wenig zwei Änderungen gleichzeitig durchzuführen, da ich, für den Fall, dass der Fehler anschliessend nicht mehr auftritt, nicht nachvollziehen könnte, was das Problem behoben hat. Zitat:
(zumal ich den Fehler nicht gezielt reproduzieren kann :?) |
Re: Ein Datensatz wird ausgewählt, mehrere geändert, warum?
Moin Zusammen,
inzwischen habe ich einen dringenden Verdacht, was die Ursache für das Problem sein könnte. Hierfür habe ich mir mal den "Spass" gemacht, ein TADODataSet.Open mit Debug-DCUs und F7 durchzugehen. Das Programm prüft regelmässig, per Timer, ob neue Sätze eingetroffen sind. Hierfür wird, wie in der problematischen Funktion, ein dynamisch erzeugter TADODataSet verwendet. Beide verwenden aber die gleiche ADOConnection. Ich habe jetzt den Verdacht, dass das Programm dadurch ins Trudeln gerät, dass die beiden DataSets den gleichen (leeren) Namen haben, und, unter bestimmten Vorausetzungen, der falsche verwendet wird. Da ich jetzt ja alle Events abschalte, sobald eine Funktion gestartet wird, dürfte das Problem wohl nicht mehr auftreten. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:49 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz