Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Commit geht nicht (SQL) (https://www.delphipraxis.net/7805-commit-geht-nicht-sql.html)

Hansa 21. Aug 2003 18:19


Commit geht nicht (SQL)
 
Hi,

folgendes Problem: ich mache ein insert/update einer Table. Im Formclose dann eine Auswahl, Commit oder Rollback. Wenn ich das committe, ist trotzdem nichts in der DB drin. Seltsam ist, daß ich bei neuen Daten im Insert lande und bei wiederholtem Eingeben im Update. Laut Delphi-Programm. Starte ich jetzt IBexpert, so ist nichts zu sehen.

Jetzt habe ich den Quellcode 1:1 mit SQL direkt übergeben, ohne Delphi und da gehts. Also kann in den SQL-Sachen kaum ein Fehler drin sein.

An Fehlermeldungen ist absolut nichts vorhanden.

kiar 21. Aug 2003 18:24

Re: Commit geht nicht (SQL)
 
arbeitest du mit transactionen?

Hansa 21. Aug 2003 18:42

Re: Commit geht nicht (SQL)
 
Natürlich, geht das auch ohne ? :shock:

[Edit]Die Transaction heißt Transaction und wird commited. 8)

kiar 21. Aug 2003 19:10

Re: Commit geht nicht (SQL)
 
welches db-system?

bei interbase gibt es unterschiede zwischen comit und commitretaining

wenn eine select abfrage mit commit beendet wird wird die ergebnismenge auf dem server verworfen und es steht nichts drin.wenn du mit commitretaining eine transaction beendest, bleibt die ergebnismenge offen und ist auf dem server verfügbar.

es sieht bei interbase aus.

Hansa 21. Aug 2003 20:53

Re: Commit geht nicht (SQL)
 
ja und dann, wie weiter ?

kiar 21. Aug 2003 21:04

Re: Commit geht nicht (SQL)
 
vielleicht solltest du mal ein paar code fetzen reinschreiben, sonst schieß ich hier weiter ins blaue :duck:

Hansa 21. Aug 2003 21:14

Re: Commit geht nicht (SQL)
 
ja, was solls:

Delphi-Quellcode:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  CASE MessageDlg('speichern ?',mtInformation,
    [mbYes, mbNo], 0) OF
    mrNo    : TransAction.Rollback;
    mrYes   : TransAction.Commit;
  END;
end;

kiar 21. Aug 2003 21:24

Re: Commit geht nicht (SQL)
 
es ist nicht gut, wenn du das commit im close event reinschreibst, dadurch werden änderungen erst beim trennen von der db -verbindung bestätigt.

mache also ein commit im afterpost event deiner dataset kompo.

Hansa 21. Aug 2003 21:33

Re: Commit geht nicht (SQL)
 
Diese Feineinstellungen sind ja schon gut, aber was tun ? Da kommt ja nichts an ? Wieso ?

kiar 21. Aug 2003 21:36

Re: Commit geht nicht (SQL)
 
auch wenn du kein commit machst ändert sich nichts in der db?

Hansa 21. Aug 2003 21:40

Re: Commit geht nicht (SQL)
 
Nein, das ist ja der Witz. :spin:

kiar 21. Aug 2003 21:45

Re: Commit geht nicht (SQL)
 
und du startest die transaction im beforinsert -event?

Hansa 21. Aug 2003 21:47

Re: Commit geht nicht (SQL)
 
Delphi-Quellcode:
procedure TForm1.FormShow(Sender: TObject);
begin
  i := 1;
  StringGrid1.fixedColor := clBtnFace +10;
  StringGrid1.Col := i;
(*
if StringGrid1.Options = goFixedVertLine then
StringGrid1.GridLineWidth := 0;
*)
  StringGrid1.Cells [0,1] := IntToStr (i)+'.';
  StringGrid1.Cells [1,0] := 'Art.Nr.';
  StringGrid1.Cells [2,0] := 'Art.Bez.';
  ...
  RecDataMod.Transaction.StartTransaction;
  LabeledEdit1.SetFocus;
end;

kiar 21. Aug 2003 21:52

Re: Commit geht nicht (SQL)
 
hansa ist ja gut :oops:

transactionen sollten nur so kurz wie möglich offen sein :!:

ich denke wir machen morgen weiter - an der gleichen stelle

mir drehen sich schon die :roteyes:

raik

Hansa 21. Aug 2003 21:56

Re: Commit geht nicht (SQL)
 
tja, wer weiß :?: Formshow -> StartTransaction. FormClose -> Commit. 8)

kiar 22. Aug 2003 09:19

Re: Commit geht nicht (SQL)
 
moin hansa

wollte mal ein prog bauen, leider funktionieren die ressourcen mit ibx icht mehr.

wenn ich heute noch hinkriege werde ich es noch machen

raik

kiar 22. Aug 2003 09:50

Re: Commit geht nicht (SQL)
 
was mir noch aufgefallen ist, das du nicht explizit die dataset bei der transaction angibts:
Delphi-Quellcode:
begin
  CASE MessageDlg('speichern ?',mtInformation,
    [mbYes, mbNo], 0) OF
    mrNo    : recmoddata.TransAction.Rollback;
    mrYes   : recmoddata.TransAction.Commit;
  end;

Hansa 22. Aug 2003 10:18

Re: Commit geht nicht (SQL)
 
Wenn ich so weiter mache, ist das halbe Programm gepostet, aber hier muß der Hund begraben liegen:

Delphi-Quellcode:
LagDS.Close;
LagDS.SelectSQL.Text := 'SELECT * FROM LAGER8 WHERE ID_ART = ';
LagDS.SelectSQL.Text := LagDS.SelectSQL.Text +
                        ArtDS.FieldByName ('ID').AsString;
LagDS.open;
aendern := NOT LagDS.IsEmpty;
LagDS.Close;
LagDS.SelectSQL.Clear;
if not aendern then begin
  LagDS.SelectSQL.Add ('INSERT INTO LAGER8 (ID,MENGE) VALUES (');
  LagDS.SelectSQL.Add (ArtDS.FieldByName ('ID').AsString);
  LagDS.SelectSQL.Add (','+IntToStr (-1*GesMenge)+')');
  LagDS.Open;
end
else begin
  LagDS.SelectSQL.Add ('UPDATE LAGER8 SET MENGE=MENGE-');
  LagDS.SelectSQL.Add (IntToStr (GesMenge));
  LagDS.Open;
end;
Zuerst suche ich einen Artikel. Ist einer da, gehts mit dem Source hier weiter. Ich prüfe ob Lagerdaten dazu exist. und dann wird der Lagerbestand halt aktualisiert. Irgendwas stimmt da nicht. Ich habe das ungute Gefühl, daß ich etwas sehr wichtiges vergessen / falsch gemacht habe, sehe aber nicht was. 8)

urs.liska 22. Aug 2003 10:25

Re: Commit geht nicht (SQL)
 
Hallo Hansa,

ich habe leider nicht die Zeit, mir einen genauen Lösungsvorschlag auszudenken, aber das Problem ist ganz klar:
Du weist die - an sich korrekte - SQL-Anweisung der SelectSQL-Eigenschaft der Dataset zu und öffnest dann die Datenmenge. Das ist aber nicht dafür gedacht. Du musst entweder mit den Insert- oder UpdateSQL-Eigenschaften arbeiten und ExecSQL aufrufen (ich weiß aber nicht genau, ob das einfach so geht oder ob erst DS.Insert->Feldzuweisung->DS.Post machen musst) oder mit TIBSQL arbeiten. Jedenfalls kannst Du mit SelectSQL keine Daten ändern ;-)

Viel Glück
Urs

Hansa 22. Aug 2003 10:36

Re: Commit geht nicht (SQL)
 
Leider bin ich heute echt blind, aber so ganz kann das nicht stimmen. Der Witz ist nämlich, wenn kein Datensatz vorhanden lande ich bei insert. Gebe ich sofort danach nochmal dasselbe ein lande ich bei Update. Gebe ich einen anderen Artikel ein wieder Insert. Also so wie es sein müßte. Aber mir fällt gerade auf, daß ich kein Post verwende. hmmmm.

urs.liska 22. Aug 2003 11:22

Re: Commit geht nicht (SQL)
 
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.

Lemmy 22. Aug 2003 11:48

Re: Commit geht nicht (SQL)
 
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

Hansa 22. Aug 2003 12:11

Re: Commit geht nicht (SQL)
 
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. :mrgreen: Thx :wall:

Hansa 22. Aug 2003 17:31

Re: Commit geht nicht (SQL)
 
Code:
DataSet.ExecSQL
gibts bei mir nicht. Geht das nicht nur mit Queries ?

kiar 22. Aug 2003 18:26

Re: Commit geht nicht (SQL)
 
frage mit welcher datenbank arbeitest du ????

raik

Hansa 22. Aug 2003 18:29

Re: Commit geht nicht (SQL)
 
im Moment : Firebird 1.0 Die Zugriffskomponenten sind aber nicht IBX, sondern FIBplus, was aber wohl egal ist.

kiar 22. Aug 2003 18:33

Re: Commit geht nicht (SQL)
 
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

Hansa 22. Aug 2003 19:10

Re: Commit geht nicht (SQL)
 
@raik: Wer wird denn wohl gleich in die Luft gehen ? :mrgreen: 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. :mrgreen:

urs.liska 23. Aug 2003 11:02

Re: Commit geht nicht (SQL)
 
Hallo Hansa,
Zitat:

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:

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:

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:

Zitat von urs.liska
Außerdem: was kiar sagt, stimmt: Transaktionen sollten so kurz wie möglich sein.

Zitat:

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).

Hansa 23. Aug 2003 12:59

Re: Commit geht nicht (SQL)
 
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:

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)

harrybo 28. Aug 2003 07:25

Re: Commit geht nicht (SQL)
 
Hi Hansa,

Du hast recht, irgendwo muss ein Post auftauchen, per Code oder über eine datensensitive Komponente (beim Wechseln des Datensatzes), denn Commit postet ja nicht automatisch. Daher ist es eine recht gängige Methode, vor dem Schließen einer Datenmenge nachzuschauen, ob der aktuelle Datensatz gerade in Arbeit ist. Ist er das, kann man posten, bzw. wie in Deinem Fall, vorher fragen:
Delphi-Quellcode:
if MessageDlg('speichern ?',mtInformation, [mbYes, mbNo], 0) = mrYes then
  with Dataset1 do begin
    if State in [dsEdit, dsInsert] then Post;
    Transaction.Commit;
  end else
    Transaction.Rollback;

Hansa 28. Aug 2003 10:48

Re: Commit geht nicht (SQL)
 
Ja, in der Richtung ist wahrscheinlich irgendwas verkehrt. Aber was ? Wo genau muß ich das edit, insert, open, close usw. aufrufen ? Die SQL-Statements enthalten ja bereits ein INSERT soll ich trotzdem noch DS.insert aufrufen ? Wenn ja wann ?

harrybo 28. Aug 2003 12:37

Re: Commit geht nicht (SQL)
 
Hi Hansa,

Deine Datasets haben unterschiedliche SQL-Properties fürs Selektieren, Inserten, Updaten, Löschen. Das Problem liegt wohl darin, dass Du über SelectSQL inserten willst (siehe Dein Code-Beispiel weiter oben).

Trage jeweils die SQL Statements in die Properties UpdateSQL, InsertSQL DeleteSQL des Datasets ein (geht auch über rechte Maustaste über einen bequemen Dialog, der Dir, nachdem Dur das SelectSQL definiert hast, automatisch die entsprechenden Statements einträgt). Dann sollte es klappen. Natürlich brauchst Du dann nicht mehr Dein SelectSQL umständlich zu switchen.

Hansa 28. Aug 2003 12:56

Re: Commit geht nicht (SQL)
 
Zitat:

Zitat von harrybo
...Trage jeweils die SQL Statements in die Properties UpdateSQL, InsertSQL DeleteSQL des Datasets ein...

Wie meinst Du das genau ? Daß das SelectSQL für den Zweck hier ungeeignet ist, wurde ja bereits gesagt. Das seltsame ist aber trotzdem, wenn ich einen neuen Datensatz einfüge scheint der da zu sein. Gebe ich dasselbe wieder ein wird der update-Teil durchlaufen, siehe Quelltext. Letztenendes landet dann aber gar nichts in der DB.

Falls es eine Spezialität von FIBplus sein sollte, weil es in deren DataSet kein ExecSQL gibt: die Frage liegt bei denen auf dem Tisch. 8)

harrybo 28. Aug 2003 13:44

Re: Commit geht nicht (SQL)
 
Hi Hansa,

ich arbeite noch mit IBX, da Du mir leider noch nicht FIBPlus aus Deiner Sammelbestellung geliefert hast ;-). Dennoch: Dein FIBPlus Dataset hat neben SelectSQL bestimmt auch die Properties UpdateSQL, DeleteSQL, InsertSQL. Wie gesagt: Properties, das sind erstmal Strings, die ein SQL Statement enthalten. Diese Properties arbeiten nun mit den Methoden Open, Post und Delete zusammen.

Angenommen Du öffnest ein Dataset mit
Code:
Dataset1.Open;
, dann wird zum Öffnen der String verwendet, der gerade in Dataset1.SelectSQL steht.
Code:
Dataset1.Post;
schickt die Insert bzw. Update SQL-Ausführungsanweisung aus Dataset1.InsertSQL, bzw. Dataset1.UpdateSQL an die DB, in Abhängigkeit davon, welchen Status Dataset1 hat (dsInsert oder dsUpdate).

Mit Dataset1.Delete verhält es sich entsprechend.

In Deinem Fall heißt das: wenn Du gerade einen Insert Befehl in SelectSQL Deines Datasets stehen hast, dann wird beim nächsten Öffnen mit Dataset1.Open ein Datensatz eingefügt, gnadenlos, ohne Meckern seitens der DB.

Ich hoffe, das bringt etwas Licht ins Dunkel. Möglicherweise erfasse ich Dein Problem auch nicht und erzähle Dir Binsenweisheiten - dann soll's denen gewidmet sein, denen es weiterhilft.

Lemmy 29. Aug 2003 11:33

Re: Commit geht nicht (SQL)
 
HI Harrybo,

Hansa macht das schon richtig! Klar, die "Standardanwendung" sieht vor, dass die SelectSQL ausgefüllt wird und die INsert-/Update-/Delete-SQL von der Komponente weitestgehend selbst ausgefüllt wird.

Allerdings kann man auch in der SelectSQL ein beliebiges SQL-Statement reinschreiben und mit ExecSQL (bei IBX) ausführen.
@Hansa: Sollte das bei FIBPlus nicht gehen, dann schau dich bei den FIBPLus nach einer Komponente vrgl. mit TIBSQL um, vielleicht auch TIBQuery. Mit der Kompo kannst Du das auf alle Fälle machen...

Grüße
Lemmy

Hansa 29. Aug 2003 11:49

Re: Commit geht nicht (SQL)
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi Lemmy,

konnte ja nur eine Frage der Zeit sein, bis ich Dich auf den Plan rufe. :lol: Ich habe zu dem Problem da gestern eine Antwort von FIBplus erhalten. Harrybo hat die schon, aber ich will sie keinem vorenthalten. Ich selber kann mich aber wohl erst heute abend intensiv damit befassen. Sieht aber auf den ersten Blick so so aus, als liefe das mit FIBplus auf eine FIBquery hinaus.

harrybo 29. Aug 2003 16:47

Re: Commit geht nicht (SQL)
 
Hi Lemmy, hi Hansa,

ich glaube, mir geht langsam die Puste aus, ich versuch's trotzdem nochmal: Hansa macht es nicht richtig, wenn am Dataset irgendwelche Data-aware components hängen. Etwa ein Grid. Wird z.B. ein Datensatz im Grid editiert und man wechselt den Datensatz, schickt das Dataset die SQL-Anweisung an den Server, die in Dataset1.UpdateSQL steht, incl. Post. Warum sollte man also seine SelectSQL ständig verbiegen, wenn man für sämtliche Schreibvorgänge eigene Properties hat, die man bequem parallel zueinander definieren kann?

Natürlich kann man in SelectSQL beliebige Statements reinschreiben, die dann auch ausgeführt werden, sagte ich ja auch schon, aber warum? Wenn in UpdateSQL, InsertSQL, DeleteSQL die entsprechenden SQL Anweisungen stehen, reicht ein Post irgendwo im Code, und es wird brav gespeichert. Daher verstehe ich auch nicht, lieber Hansa, warum es jetzt auf ein Query hinauslaufen soll, das eignet sich gerade nicht zum Schreiben in die DB, dann nimm lieber eine reine SQL Komponente, allerdings kann man an diese keine datensensitiven Objekte ranhängen.

Was ich gestern Hansa geantwortet habe:
Code:
ich will                            geeignete Komponente
--------------------------------------------------------- 
Daten über Grid manipulieren        TIBDataset
Daten in Grid nur anzeigen          TIBQuery
direkt mit der DB arbeiten          TIBSQL
TIBSQL hat daher auch ExecSQL, da es zum direkten Ausführen von SQL Befehlen konzipiert wurde. Wenig Speicherbedarf und um ein zigfaches schneller als die beiden anderen Komponenten. Du kannst mit TIBSQL etwa in allen Datensätzen einen Wert in ein Feld schreiben. Selbst, wenn das tausende sind, zuckt der Server höchstens mal kurz. Klar, das geht auch mit Queries, aber die sind nun mal zur Datenansicht, also für den Lesezugriff da, schleppen auch alles mit, was man dafür braucht, also wozu dann instanzieren für ein einfaches INSERT...?

Lemmy 30. Aug 2003 09:07

Re: Commit geht nicht (SQL)
 
Hi Harrybo,

ja, Du hast recht, aber nur fast!

Jeff Overcash hat einmal gesagt, dass die TIBQuery nur aus kompatibilitätsgründen bei IBX dabei ist, anstelle der TIBQuery sollte immer die TIBDataSet verwendet werden. Es kann aber auch sein, dass sich inzwischen der Stellenwert die TIBQuery geändert hat und ich das nicht mitbekommen habe.....

Natürlich ist die TIBSQL schneller, da diese weniger Overhead mit rumschleppen muss als die TIBDataSet. Hast Du schon mal mit Int64 in deiner Datenbank gearbeitet?? Sobald Du diese Werte bei ParamByName zuweisen willst, wird es beim TIBSQL/TIBStoredProcedure richtig aufwändig, die diese beiden Kompos keine Int64-Felder unterstützen!!! Aus diesem Grund arbeite ich (fast) nur noch mit TIBDataSet....

Grüße
Lemmy

Hansa 1. Sep 2003 09:54

Re: Commit geht nicht (SQL)
 
Hi Leute,

das ganze geht jetzt und es sieht so aus, daß der Hund bei FIBplus begraben ist. 8) Ist aber nichts schlimmes. Man hat mir gesagt, ich solle gefälligst pFIBQuery verwenden ! :mrgreen: Jetzt habe ích das gemacht und siehe es geht alles wie gewünscht. D.h. ich setze die SQL-Statements und mit ExecQuery kommt dann das richtige Ergebnis.


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:33 Uhr.
Seite 1 von 2  1 2      

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