Autor Beitrag
Agawain
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 460

win xp
D5, MySQL, devxpress
BeitragVerfasst: Di 09.10.07 23:19 
tja

hab mal wieder ein Problem, was ich nicht versteh:

ist was komplizierter...also es geht darum, dass ein Storno-Beleg erstellt werden soll.

Dafür steht eine Datenmenge Beleg_Liste und eine Datenmenge Belege zur Verfügung.
Das Formular Rechnung bekommt seine Daten aus Belege und mit Beleg_Liste wird das überhaupt angesteuert...also welcher Beleg storniert werden soll.
Verfahren...User markiert den entsprechenden Datensatz, der auf Beleg_liste basiert und klickt doppelt drauf...dann wird der Beleg, also das Form angezeigt...nun kann er den Button Storno klicken..., dann baut sich das Formular neu auf mit der Datenmenge Belege...wird also schlicht der Datensatz von Beleg_liste reinkopiert in Belege und das Formular bekommt die dann.

Soweit so gut, nur jetzt zickt da was rum, ich vermute MyDac...stellt sich folgendermaßen dar...

wenn der User Feldinhalte des Forms ändert und schließlich den Beleg drucken will...
sagt beleg_liste, daß 0 records found for update...nur...ich hab bis zur Drucklegung des Belegs das Grid und damit auch Beleg_liste gesperrt, so daß der User den Datensatz dazwischen nicht wechseln kann, denn die beden Forms Liste und Beleg bestehen ja relativ unabhängig voneinander.
Trotzdem, die Druckroutine, die auch zuständig ist für die Belegnummernvergabe muss im Falle Storno auf den DS in Beleg_liste zurückgreifen...also der Storno bekommt seine Belegnummer, dann muß er in Beleg_liste seine Beleg_nummer vermerken, damit eine Referenz der Belege untereinander da ist.

Es funktioniert...wenn man einfach Storno aufruft und nichts mehr am Beleg ändert....aber wie gesagt, wenn man in Belege was ändert...*knirscht es, ich raff es nicht.

Und jetzt kommt mir nicht mit Quelltext zeigen...das geht in solchen Fällen fast gar nicht...hoff nur, dass mich Jemand vielleicht über ne Macke von MyDac aufklären kann.

Oder ich weiß nicht wo der Denkfehler ist.

Gruß

Aga


Zuletzt bearbeitet von Agawain am Di 09.10.07 23:24, insgesamt 1-mal bearbeitet
ene
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 779
Erhaltene Danke: 1

Vista, XP, W2K
Delphi, .Net, Deutsch und Englisch
BeitragVerfasst: Mi 10.10.07 07:26 
Moin,

du hast eine Tabelle Beleg_Liste und eine Tabelle Belege? Über Forms greifst du auf die Tabellen zu und öffnest aus der Beleg_Liste die Belege? Im Form Beleg hast du einen Knopf zum Stornieren? Was wird dabei wie storniert? Und zumindest der Quellcode oder die SQL-Abfrage wären doch von Interesse ;)

_________________
Wir, die guten Willens sind, geführt von Ahnungslosen, Versuchen für die Undankbaren das Unmögliche zu vollbringen.
Wir haben soviel mit so wenig so lange versucht, daß wir jetzt qualifiziert sind, fast alles mit Nichts zu bewerkstelligen.
Agawain Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 460

win xp
D5, MySQL, devxpress
BeitragVerfasst: Mi 10.10.07 11:27 
Hi ene

im Nachhinein finde ich es für Außenstehende etwas wirr, was ich geschrieben habe, aber so wirr ist es gar nicht.

Also vom kaufmännischen Ablauf her, ich habe eine Rechnung und die soll storniert werden.

Datentechnisch und auch papiertechnisch bedeutet das, daß ein neuer Beleg erstellt wird, nämlich der Storno-Beleg.
Bei einem Vollstorno wird ein identischer Datensatz erstellt, nur daß der halt Soll-Haben-technisch auf der anderen Seite gebucht wird und textmäßig etwas anders aussieht.
In meinem Fall kommt noch das Elend mit den zig Nummernkreisen dazu, aber das ist ne andere Geschichte.

Also ich habe beleg_liste (master-detail query in Bezug auf den Kunden) , aus der ich die Rechnung bzw. den Beleg auswähle, den es zu stornieren gilt.
Wenn der User im Formular den Storno-Button klickt, wird in der Tabelle belege ein neuer Datensatz eingefügt und mit den Werten des Datensatzes aus beleg_liste befüllt.
Der neue Datensatz bekommt außerdem die Belegnummer von dem alten Datensatz als Referenznummer mit.
Vice Versa muß nun dasselbe geschehen, d.h. der neue Datensatz muß dem alten Datensatz mitteilen, welche Nummer er bekommen hat, bei Erstellung weiß er das aber noch nicht, das geschieht erst bei Abschluß des Beleges, wenn er gedruckt wird.
belege ist ein seperates query, welches nur dem Form Beleg gehört.
Etwas Wesentliches habe ich gestern noch vergessen zu erwähnen und das ist, bei der Belegnummernvergabe wird eine Transaktion auf die Tabelle Nummernkreis mit SELECT FOR UPDATE eingeleitet und da es sich ja um MySQL handelt ist die Engine InnoDB
Innerhalb der Transaktion wird dann dem alten Beleg mitgeteilt, zu welchem Storno-Beleg er gehört, außerdem werden ein paar Status- Datumsfelder gesetzt und das Feld Offener Posten geändert, sowohl im Beleg, als auch im Storno-Beleg.

Wie gesagt, das alles funktioniert prächtig, solange der User nichts anderes macht, als den Storno-Button zu drücken und anschließend die Quasi-Kopie, also den Storno-Beleg unverändert zu bestätigen.

Er kann auch in dem neuen Beleg Veränderungen vornehmen, die auch gespeichert werden :!:
ABER wenn er dann, also nach Änderung durch Drucken die Nummernvergabe anstößt, heißt auch die Transaktion einleitet, bekommt der Storno-Beleg ne neue Nummer und wenn dann in den alten Datensatz zurückgeschrieben werden soll, knallts.
Irgendwie muß das mit der Transaktion zu tun haben, die nach dem Fehlerfall auch macht, was sie soll, nämlich alles rückgängig...Aber was ich absolut nicht versteh, warum ich in einem Fall auf den Ur-Beleg zugreifen kann und in dem anderen Fall, wenn also im Storno-Beleg was geändert wurde, nicht, mit denselben Lese- und Speicherroutinen.
Deswegen nutzt SQL hier wenig...irgendwie verbiegt sich bei MyDac da was intern.

:cry:

Na ja, hab ja kaum Hoffnung, daß mir da Jemand weiterhelfen kann, war jedenfalls schön, mal drüber geredet zu haben :wink:
ene
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 779
Erhaltene Danke: 1

Vista, XP, W2K
Delphi, .Net, Deutsch und Englisch
BeitragVerfasst: Mi 10.10.07 11:40 
Zitat:
war jedenfalls schön, mal drüber geredet zu haben :wink:


Genau das dachte ich auch gerade. Arbeitest du denn mit Transaktionen oder führst du die SQL-Statements direkt aus? Der neue DS ist durch den Benutzer gesperrt, vielleicht hilft es ja die andere Abfrage als SnapShot zu öffnen um die Bearbeitung zu erlauben.

Ganz hinterher komme ich dabei immer noch nicht.

_________________
Wir, die guten Willens sind, geführt von Ahnungslosen, Versuchen für die Undankbaren das Unmögliche zu vollbringen.
Wir haben soviel mit so wenig so lange versucht, daß wir jetzt qualifiziert sind, fast alles mit Nichts zu bewerkstelligen.
Agawain Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 460

win xp
D5, MySQL, devxpress
BeitragVerfasst: Do 11.10.07 23:48 
hi nochmal

so bin wahrscheinlich der Lösung gedanklich ein Stück näher gekommen.
Aber um die offenen Fragen zu beantworten:
select for update lockt den betreffenden Satz www.crlab.com/forums...amp;highlight=#1706e Transaktion, also ich arbeite mit Transaktionen, nicht immer, aber gerade bei der sensiblen Rechnungsnummervergabe schon.

Innerhalb der Transaktion finden mehrere Tabellenupdates statt, nämlich wie gesagt beim Referenzbeleg, also dem eigentlichen Urbeleg, natürlich der Tabelle Nummernkreis und dem Storno-Beleg selbst.

Bevor ich die Sache mit Referenznummern in den Urbeleg reinschreiben eingebaut habe, funktionierte das auch noch einwandfrei, auch wenn der User den neuen Beleg geändert hat.

Auch bei einer Belegneuerstellung selbes Formular, selbe Routinen, das heißt auch da werden im neuen Beleg Stati gesetzt und OP-Feld gefüllt in der Transaktion, klappt alles nach wie vor.

so nun
Corelab sagt zur Fehlermeldung das:
www.crlab.com/forums...&highlight=#1706

eindeutig indiziert ist die Tabelle...usw.

Das einzige was hier in Frage kommt, no record suits for the update

und das hat mich auf die Idee gebracht, dass möglicherweise doch nicht i_beleg_liste betroffen ist sondern belege.
Als wenn die Transaktionskontrolle über veraltete Informationen verfügt...
So wie man auch mehr oder weniger, haptsächlich weniger sichere Transaktionen bei MySQL machen kann:

Das geht so, man fügt ein Feld timestamp ein, das wird von der Datenbank immer bei Erstellung und Veränderung des Datensatzes versorgt.
ok, man liest den Datensatz ein, hält den timestamp im Sinn und wenn man zurückschreiben will, liest man den Datensatz noch mal neu ein, vergleicht die beiden timestamps, sind die unterschiedlich, darf der Datensatz nicht zurückgeschrieben werden, weil sich in der Zwischenzeit Änderungen ergeben haben.

Irgendwas in der Richtung ist das, käme dann auch mit dem sehr wenig aufschlußreichen Comment *no suiting record* hin.

Die Empfehlung von denen, einfach das raising der exception restrictupdate := false....ne...das könnts ja sein, weil sich innodb da im Irrtum befindet, aber das mißhagt mir sehr.

Evtl. reicht ja auch ein Neueinlesen des Datensatzes...hab nur momentan keine Zeit das zu testen, weil ich versinke gerade in normaler Büroarbeit.

Na wie gesagt, nur ein Verdacht, von der Symptomatik her paßt es, wenn wer noch andere Ideen oder Erfahrungen hat, immer her damit...

einfach crude :autsch:

Gruß

Aga
ene
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 779
Erhaltene Danke: 1

Vista, XP, W2K
Delphi, .Net, Deutsch und Englisch
BeitragVerfasst: Fr 12.10.07 07:29 
Dann würde ich deine Tests erst mal abwarten ;)

_________________
Wir, die guten Willens sind, geführt von Ahnungslosen, Versuchen für die Undankbaren das Unmögliche zu vollbringen.
Wir haben soviel mit so wenig so lange versucht, daß wir jetzt qualifiziert sind, fast alles mit Nichts zu bewerkstelligen.