AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Commit geht nicht (SQL)
Thema durchsuchen
Ansicht
Themen-Optionen

Commit geht nicht (SQL)

Ein Thema von Hansa · begonnen am 21. Aug 2003 · letzter Beitrag vom 1. Sep 2003
Antwort Antwort
Seite 3 von 5     123 45      
urs.liska

Registriert seit: 6. Aug 2003
Ort: Freiburg
195 Beiträge
 
Delphi 6 Professional
 
#21

Re: Commit geht nicht (SQL)

  Alt 22. Aug 2003, 11:22
Verständnisfrage: Du willst eingeben, dass Artikel in das Lager eingestellt werden, richtig (wenn es auch um rausnehmen geht, verstehe ich nicht, wozu dann das Insert gut sein sollte)?
Ist LAGER8.ID_ART der Fremdschlüssel, der auf den Artikel zeigt? Und die Artikeltabelle hat ID als Primärschlüssel? So sieht das zumindest im ersten Teil des Postings aus (wenn du 'aendern' ermittelst).
Ich nehme auch an, dass ArtDS während des ganzen Vorgangs geöffnet ist und GesMenge eine lokale Variable ist, die irgendwie aus ArtDS o.ä. ermittelt wird.

Wenn das so ist, musst Du aber beim Insert sagen: "INSERT INTO LAGER8 (ID_ART, MENGE)...", denn Du willst ja die Artikelnummer in das Fremdschlüsselfeld eintragen und nicht in den Primärschlüssel der Lager-Tabelle. (Ich nehme an, Du hast für LagDS eine Regelung für das AutoInc-Feld?). Ich weiß nicht, ob dieser Fehler das ungewöhnliche Verhalten Deiner Anwendung verursacht, aber es ist auf jeden Fall ein Fehler, den Du ausmerzen musst (vielleicht hast Du ihn nur noch nicht bemerkt, weil ja keine Daten eingetragen werden).

Und: bei der UPDATE-Anweisung fehlt unbedingt die WHERE-Klausel (WHERE ID_ART = 'aktuelle Artikelnummer'), sonst änderst Du alle Datensätze!!! statt ID_ART kannst Du auch nach ID suchen und einen Wert eintragen, den du in der ersten Abfrage zwischengespeicherthast:
Delphi-Quellcode:
lagDS.open;
if not LagDS.IsEmpty then
begin
  aendern := true;
  LagId := LagDS.FieldByName('ID').AsInteger;
end;
...
  LagDS.SelectSQL.Add ('UPDATE LAGER8 SET MENGE=MENGE-');
  LagDS.SelectSQL.Add (IntToStr (GesMenge));
  LagDS.SelectSQL.Add ('WHERE ID = ' + IntToStr(LagId));
Außerdem: was kiar sagt, stimmt: Transaktionen sollten so kurz wie möglich sein. Also nicht beim Öffnen des Fensters starten und beim Schließen beenden. Die Transaktion sollte vor Beginn des zusammenhängenden Vorgangs gestartet und nach Abschluss desselben beendet werden. Sie dient nur dazu, zu garantieren, dass die zusammenhängenden Buchungen nicht nur teilweise durchgeführt werden. Transaktionen sind nicht dazu da, bei Datenbanken so etwas wie ein "Dokument" zu simulieren, das erst am Ende der Sitzung gespeichert wird! Wenn Dir das wichtig ist, solltest Du so etwas wie einen Log-Mechanismus verwenden, der alle Änderungen während der Sitzung speichert, um diese ggfs. rückgängig machen zu können. Im Prinzip geht das auch mit Cached Updates oder ClientDataSets...

Wenn Du sicher weißt, dass Deine Anwendung nur von sehr wenigen Benutzern oder gar nicht im Netzwerk ausgeführt wird, kannst Du Dich aber auch über diese Regeln hinwegsetzen, da sie vor allem dann ins Gewicht fallen, wenn gleichzeitig verschiedene Transaktionen (z.B. von verschiedenen Usern) aktiv sind.

Es gibt noch einen Aspekt. IBX (ich nehme an, Du nimmst die) regelt Transaktionen automatisch, wenn Du sie nicht explizit steuerst. D.h. die Transaktion ist (so wie Du es bisher machst) nur dann während der ganzen Sitzung aktiv, wenn sie den Datenmengen auch korrekt zugeordnet ist (Also IBDatabase.DefaultTransaction auf die Transaktion zeigt und die DataSets auf die entsprechende Datenbank). Wenn hier etwas nicht klar sein sollte, ist in jedem Fall mit ungewöhnlichem Verhalten der Anwendung zu rechnen.

Also:
1) ich würde es dennoch mit der IBSQL-Komponente versuchen, das entspricht einfach dem, was Du tun willst. Ansonsten probier mal, was mit Post passiert (würde mich aber wundern, wenn es doch funktioniert).
2) würde ich die beiden Fehler in den SQL-Anweisungen korrigieren
3) würde ich die Transaktion direkt in die Routine legen
Und ich würde die Veränderungen einzeln machen und testen, nicht alles auf einmal, sonst weißt Du nicht, was passiert ist.

Viel Erfolg
Urs

P.S.
nach nochmaligem Durchlesen fällt mir auf, dass ich keine wirkliche Antwort auf das eigentlich ungewöhnliche Verhalten der Anwendung gefunden habe. Aber ich bin ziemlich sicher, dass dieses mit der falschen (? oder doch zumindest unorthodoxen Verwendung von SelectSQL zu tun hat). Und die Fehler, die ich angesprochen habe, würden in jedem Fall zu Tage treten, wenn Du Dein erstes Problem gelöst hast.
  Mit Zitat antworten Zitat
Lemmy

Registriert seit: 8. Jun 2002
Ort: Berglen
2.366 Beiträge
 
Delphi 10.3 Rio
 
#22

Re: Commit geht nicht (SQL)

  Alt 22. Aug 2003, 11:48
Hi Hansa,

warum machst Du beim Update bzw. Insert ein

DataSet.open???

Sollte da nich DataSet.ExecSQL; stehen?!? Open macht man nur bei Select, alles andere funzt mit ExecSQL....

Grüße
Lemmy
  Mit Zitat antworten Zitat
Hansa

Registriert seit: 9. Jun 2002
Ort: Saarland
7.554 Beiträge
 
Delphi 8 Professional
 
#23

Re: Commit geht nicht (SQL)

  Alt 22. Aug 2003, 12:11
Ups, ja open ? Dafür macht der nichts. 8) Jetzt muß ich weg und kann es nicht mal testen. Dafür drucke ich mir das von urs.liska aus und nehm es mit. Und wenn ich einen Blindenhund sehe kauf ich den dann noch. Thx
Gruß
Hansa
  Mit Zitat antworten Zitat
Hansa

Registriert seit: 9. Jun 2002
Ort: Saarland
7.554 Beiträge
 
Delphi 8 Professional
 
#24

Re: Commit geht nicht (SQL)

  Alt 22. Aug 2003, 17:31
Code:
DataSet.ExecSQL
gibts bei mir nicht. Geht das nicht nur mit Queries ?
Gruß
Hansa
  Mit Zitat antworten Zitat
Benutzerbild von kiar
kiar

Registriert seit: 2. Aug 2003
Ort: Aschersleben
1.362 Beiträge
 
Delphi 5 Professional
 
#25

Re: Commit geht nicht (SQL)

  Alt 22. Aug 2003, 18:26
frage mit welcher datenbank arbeitest du ????

raik
  Mit Zitat antworten Zitat
Hansa

Registriert seit: 9. Jun 2002
Ort: Saarland
7.554 Beiträge
 
Delphi 8 Professional
 
#26

Re: Commit geht nicht (SQL)

  Alt 22. Aug 2003, 18:29
im Moment : Firebird 1.0 Die Zugriffskomponenten sind aber nicht IBX, sondern FIBplus, was aber wohl egal ist.
Gruß
Hansa
  Mit Zitat antworten Zitat
Benutzerbild von kiar
kiar

Registriert seit: 2. Aug 2003
Ort: Aschersleben
1.362 Beiträge
 
Delphi 5 Professional
 
#27

Re: Commit geht nicht (SQL)

  Alt 22. Aug 2003, 18:33
ne ist es nicht. wir sind die ganze zeit von ibx ausgegangen. denn da geht bei dataset auch execsql.

so da wir das nun geklärt haben und ich nicht fibplus arbeite und diese auch nicht kenne verabschiede ich mich hiermit.

sorry raik
  Mit Zitat antworten Zitat
Hansa

Registriert seit: 9. Jun 2002
Ort: Saarland
7.554 Beiträge
 
Delphi 8 Professional
 
#28

Re: Commit geht nicht (SQL)

  Alt 22. Aug 2003, 19:10
@raik: Wer wird denn wohl gleich in die Luft gehen ? Das Wort IBX wurde hier bisher einmal erwähnt. Du selber hast nur nach der Datenbank gefragt. Die Frage mit ExecSQL werde ich schon noch klären.

Dann frag ich mal @Lemmy : Du kennst doch auch FIBplus, weißt Du da nichts drüber auf die Schnelle, bevor Raik abhaut?

@urs.liska:

Finde ich schon stark, wie Du meinen Quelltext zerpflückt hast. Das ist nicht ironisch gemeint

Zitat:
Verständnisfrage: Du willst eingeben, dass Artikel in das Lager eingestellt werden, richtig (wenn es auch um rausnehmen geht, verstehe ich nicht, wozu dann das Insert gut sein sollte)?
Ganz einfach, weil es Leute gibt, die Sachen verkaufen, die noch nicht im Lager gebucht sind. Dadurch können sogar negative Lagerbestände entstehen. Das Programm sollte schon in der Lage sein, mit so was umzugehen. Umsatz ist schon wichtiger, als das Lager. Zum Schluß muß natürlich wieder alles stimmen.

Zitat:
...musst Du aber beim Insert sagen: "INSERT INTO LAGER8 (ID_ART, MENGE)..."
Klar, ich wollte euch nicht noch mehr zumuten und habe hier im Editor etliches weggelöscht, damit man sofort den Kern des Problems sieht. Im Original steht schon ID_ART drin.

Zitat:
Und: bei der UPDATE-Anweisung fehlt unbedingt die WHERE-Klausel (WHERE ID_ART = 'aktuelle Artikelnummer')
Stimmt, das war ein kapitaler Fehler und der war wirklich da drin. Ich habe hier zwar schon Daten überall, aber das ist mir nicht aufgefallen, 8) weil die Daten nur per Insert aus alten Daten stammen. Update ist mir ja noch nicht gelungen.

Zitat:
Außerdem: was kiar sagt, stimmt: Transaktionen sollten so kurz wie möglich sein.
Ist auch klar, aber dazu muß ich einen neuen Thread aufmachen. Im Zusammenhang mit Transaktionen ist mir einiges noch unklar, auch mit der DefaultTransaction und und. Und ein Programm unter der Maxime zu schreiben: das läuft niemals im Netzwerk, das gewöhne ich mir gar nicht erst an. So was überlasse ich Bill Gates mit seinen 640 KB, die angeblich für immer reichen.
Gruß
Hansa
  Mit Zitat antworten Zitat
urs.liska

Registriert seit: 6. Aug 2003
Ort: Freiburg
195 Beiträge
 
Delphi 6 Professional
 
#29

Re: Commit geht nicht (SQL)

  Alt 23. Aug 2003, 11:02
Hallo Hansa,
Zitat von Hansa:
Finde ich schon stark, wie Du meinen Quelltext zerpflückt hast. Das ist nicht ironisch gemeint
Hatte ja eigentlich keine Zeit, konnte mich dann aber doch nicht zurückhalten.

Zitat von urs.liska:
Verständnisfrage: Du willst eingeben, dass Artikel in das Lager eingestellt werden, richtig (wenn es auch um rausnehmen geht, verstehe ich nicht, wozu dann das Insert gut sein sollte)?
Zitat von Hansa:
Ganz einfach, weil es Leute gibt, die Sachen verkaufen, die noch nicht im Lager gebucht sind. Dadurch können sogar negative Lagerbestände entstehen. Das Programm sollte schon in der Lage sein, mit so was umzugehen. Umsatz ist schon wichtiger, als das Lager. Zum Schluß muß natürlich wieder alles stimmen.
Aha. Seltsame Sache, das, etwas zu verkaufen, was man gar nicht hat Aber so ist mir klar, was es soll. In dem Zusammenhang wäre es vielleicht nett, in den Triggern AFTER INSERT und AFTER UPDATE (bei Firebird 1.5 geht das dann in einem Trigger!) ein EVENT auszulösen, falls MENGE < 0 ist. (Aber wenn Du so viel rausgelöscht hast, hast Du ja vielleicht daran auch schon gedacht).

Zitat von urs.liska:
Außerdem: was kiar sagt, stimmt: Transaktionen sollten so kurz wie möglich sein.
Zitat von Hansa:
Und ein Programm unter der Maxime zu schreiben: das läuft niemals im Netzwerk, das gewöhne ich mir gar nicht erst an.
Sehr vernünftig (Auch das ist nicht ironisch gemeint).
Viel Erfolg. Wahrscheinlich sehen wir uns im Transaktionen-Thread wieder, denn ich habe zwar in meinem letzten Beitrag kategorische Lehrmeistersätze von mir gegeben, aber wirklich praktische Erfahrungen habe ich auch noch recht wenige (ich sitze gerade an meiner ersten _größeren_ DB-Anwendung, die ich "sauber" machen will )

MFG
Urs

P.S. ich kenne mich auch nicht mit FIBPlus aus. Sorry.
Aber ich weiß, dass die verschiedenen spezialisierten DB-Komponentensammlungen insbesondere beim Caching, also dem Zwischenspeichern der Daten, eigene Wege gehen (oft, um die Performance zu steigern). Ich halte es daher weiterhin für nahe liegend, dass Dein "Datenverlust" damit zusammen hängt, dass Du die Daten mit der falschen Methode (SelectSQL) einfügst. Die Tatsache, dass Du in Deiner Anwendung nach einem Insert die Daten sehen kannst(was ich mir bis jetzt nicht wirklich erklären kann), könnte mit so einem FIBPlus-spezifischen Caching-Phänomen zusammen hängen. Daher nochmal der Tipp: suche Dir eine Komponente, die SQL-Anweisungen "Executed" und nicht "öffnet", d.i. entweder eine DataSet mit InsertSQL/UpdateSQL oder eine spezielle SQL-Komponente (bei IBX heißt die TIBSQL).
  Mit Zitat antworten Zitat
Hansa

Registriert seit: 9. Jun 2002
Ort: Saarland
7.554 Beiträge
 
Delphi 8 Professional
 
#30

Re: Commit geht nicht (SQL)

  Alt 23. Aug 2003, 12:59
Hier ist noch was, hat zwar mit dem Thema direkt nichts zu tun, aber es ist sehr wichtig. Wer IBX benutzt muß das hier unbedingt lesen :

Zitat von urs.liska:
In dem Zusammenhang wäre es vielleicht nett, in den Triggern AFTER INSERT und AFTER UPDATE (bei Firebird 1.5 geht das dann in einem Trigger!)
Aus dem Zusammenhang heraus vermute ich, daß Du IBX verwendest. Jetzt lese ich hier was von Firebird und dann noch 1.5. Vielleicht weißt Du tatsächlich nicht, daß IBX definitiv NICHT für Firebird weiterentwickelt wird. Für eventuelle Besonderheiten gegenüber Interbase wird dreimal nichts gemacht. Und das ist kein Gerücht, sondern wurde mehrmals ganz öffentlich von Jeff Overcash gesagt.

In neuerer Zeit ist einiges passiert. Und sieht man sich mal die Datenblätter von Firebird 1.5 und Interbase 7.1 an, so wird man schon deutliche Unterschiede feststellen. Mit IBX geht das IMHO nicht mehr lange gut. So, was ist jetzt zu tun ? Entweder man zahlt jedesmal für Interbase und benutzt die kostenlosen IBX oder man nutzt die kostenlose Firebird-DB und zahlt einmal z.B. für FIBplus (<200$). Das ist der Hauptgrund warum ich FIBplus verwende, zumal mir auch von deren Seite versichert wurde, sowohl das kommerzielle Interbase als auch Firebird würden beide in Zukunft unterstützt.

Kommt es aufs Geld an, dann nehme ich doch lieber Firebird. Ist einer ein Angsthase und traut OpenSource Projekten nicht, tja dann muß er eben für Interbase zahlen. Der Haken an der Sache liegt auf der Hand: ich kann die kommenden Verbesserungen nur schlecht verwenden. Sollte da etwas gravierend wichtiges kommen, kann ich aber immer noch mit Compiler-Direktiven hantieren. Und ob es boolsche-Typen in IB gibt, oder ich 1 und 0 verwende interessiert mich die Bohne. 8)
Gruß
Hansa
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 3 von 5     123 45      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:24 Uhr.
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