Alle Datensätze werden geändert

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Antworten
Luckner
Beiträge: 88
Registriert: Sa 18. Jan 2020, 09:56
OS, Lazarus, FPC: Winux (L 2.2.0 FPC 3.2.2)
CPU-Target: Windows 64-Bit

Alle Datensätze werden geändert

Beitrag von Luckner »

Hallo,
habe gerade ein Problem, das ich nicht verstehe, weil an anderen Stelle (andere Tabelle) nach dem gleichen Muster verfahren wird. Habe in einem Frame ein DBGrid, in dem ich,
über ein DatasetGrid, alle Datensätze der Tabelle einzeige. Mit einem Doppelklick auf auf die Tabelle, hole ich mir einen Datensatz, mit der entsprechenden ID und ein IBDataSetAdressen , in die EditFelder. Eine Änderung eines Feldes und das Abspeichern, bewirkt das alle Datensätze dieser Tabelle mit den selben Änderungen überschrieben werden. Was mich jetzt auch wundert, dass auch die Felder ID ebenfalls mit der aktl. ID beschrieben werden. als ob es eine Kopie des Datensatzes auf alle Sätze der Tabelle gemacht werden. An einer anderen Stelle mit einer anderen Tabelle funktioniert es.

Code: Alles auswählen

procedure TFrameAdressen.ButtonSpeichernClick(Sender: TObject);
begin 
     DataModule_AdressenStamm.IBTransactionAdressen.Active:= true;
      DataModule_AdressenStamm.IBDataSetAdressen.Open;

      LabelTest2.Caption:= IntToStr(AdressenID); //Hier wird die aktl. ID des Datensatzes angezeigt

      DataModule_AdressenStamm.IBDataSetAdressen.Edit;

      if EditKurzbezeichnung.Text = '' THEN
        DataModule_AdressenStamm.IBDataSetAdressenADRESSENCODE.Clear
      else
        DataModule_AdressenStamm.IBDataSetAdressenADRESSENCODE.AsString := EditKurzbezeichnung.Text;
        
      if MemoAdresse.Text = '' then
        DataModule_AdressenStamm.IBDataSetAdressenADRESSE.Clear
      else
        DataModule_AdressenStamm.IBDataSetAdressenADRESSE.AsString := MemoAdresse.Text;

      if EditAdressenLand.Text = '' then
        DataModule_AdressenStamm.IBDataSetAdressenLAND.Clear
      else
        DataModule_AdressenStamm.IBDataSetAdressenLAND.AsString := EditAdressenLand.Text;

      if EditAdressenPlz.Text = '' then
        DataModule_AdressenStamm.IBDataSetAdressenPLZ.Clear
      else
        DataModule_AdressenStamm.IBDataSetAdressenPLZ.AsInteger := StrToInt(EditAdressenPlz.Text);

      if EditAdressenOrt.Text = '' then
        DataModule_AdressenStamm.IBDataSetAdressenORT.Clear
      else
        DataModule_AdressenStamm.IBDataSetAdressenORT.AsString := EditAdressenOrt.Text;

      if EditAdressenVorwahlTel.Text = '' then
        DataModule_AdressenStamm.IBDataSetAdressenFON_VORWAHL.Clear
      else
        DataModule_AdressenStamm.IBDataSetAdressenFON_VORWAHL.AsInteger := StrToInt(EditAdressenVorwahlTel.Text);

      if EditAdressenTelNr.Text = '' then
        DataModule_AdressenStamm.IBDataSetAdressenFON_NUMMER.Clear
      else
        DataModule_AdressenStamm.IBDataSetAdressenFON_NUMMER.AsInteger := StrToInt(EditAdressenTelNr.Text);  
     
     DataModule_AdressenStamm.IBDataSetAdressen.Post;

      if DataModule_AdressenStamm.IBTransactionAdressen.InTransaction then DataModule_AdressenStamm.IBTransactionAdressen.Commit;
      DataModule_AdressenStamm.IBTransactionAdressen.StartTransaction;
 end; 
Ist 'DataModule_AdressenStamm.IBDataSetAdressen.Post' an dieser Stelle richtig, oder wäre ein 'DataModule_AdressenStamm.IBDataSetAdressen.Update' besser?

Schreibe eine funktionierende Anwendung, die unter Delphi 7 programmiert worden ist auf Lazarus.

Bitte um Hilfe.

Danke, Andreas

Luckner
Beiträge: 88
Registriert: Sa 18. Jan 2020, 09:56
OS, Lazarus, FPC: Winux (L 2.2.0 FPC 3.2.2)
CPU-Target: Windows 64-Bit

Re: Alle Datensätze werden geändert

Beitrag von Luckner »

Nachtrag.
Habe jetzt auf 'DataModule_AdressenStamm.IBDataSetAdressen.ApplyUpdates' umgestellt. Das Teil mit den Transactionen auch komplett weggelassen. In dem entsprechendem Dataset habe ich unter 'modify' auch ID rausgenommen. Dadurch wird das Feld ID in der Tabelle nicht mehr aktualisiert. Aber alle anderen Datensätze schon. Leider.

Andreas

charlytango
Beiträge: 843
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: Alle Datensätze werden geändert

Beitrag von charlytango »

Nur einfach zur Info....

Implizite Editfelder (also solche die gleichzeitig an der gleichen Datasource eines DBGrid hängen) verwende ich in meiner Applikationsentwicklung nicht (mehr - das war für mich schon zu Delphi7 Zeiten obsolet).
Oder anders formuliert: wildes herumeditieren ihn Feldern lasse ich nicht mehr zu.

Jedes Formular auf dem editierbare Felder aus einer Tabelle vorkommen, hat seine eigene DataSource die beim Erzeugen des Formulars mit dem globalen Zugriffsobjekt zur Datenbank verbunden wird. Grids zur Übersicht und zum Suchen, Formulare zum Editieren (auch wenn sie in einer Form gedocked sein sollten)

Die Formulare sind fast immer erst einmal im View Modus (d.h. die Felder sind disabled). Einen Editiervorgang muss der Benutzer aktiv anstoßen (Button drücken, F2 etc.). Vor dem eigentlichen Editieren wird in jedem Fall noch der Datensatz bzw auch mittels logischer Sperre ein ganzer Themenkomplex (Rechnung XY) gesperrt.
Die Daten werden erst beim aktiven Drücken eines "Speichern"-Buttons zurück in die Datenbank geschrieben (ohne weitere Prüfung da ja nur auf gesperrten Daten editiert werden kann)

Danach werden etwaige History-Arbeiten erledigt und evtl damit verbundene DataSources informiert um eine Aktualisierung anzustoßen.

Des weiteren habe ich mir schon lange abgewöhnt dass Grids alle Daten anzeigen. Das geht nur in Ausnahmefällen und ist entsprechend geschützt. Otto Normaluser darf sich immer aussuchen welcher Teil der Daten im Grid angezeigt werden soll.

Zugegeben, bei wirtschaftlichen Applikationen klappt das besser als bei technischen Programmen. Aber im wesentlichen ist das meine Strategie.

Luckner
Beiträge: 88
Registriert: Sa 18. Jan 2020, 09:56
OS, Lazarus, FPC: Winux (L 2.2.0 FPC 3.2.2)
CPU-Target: Windows 64-Bit

Re: Alle Datensätze werden geändert

Beitrag von Luckner »

Hallo charlytango,

habe vergessen hier einzutragen, dass das Grid natürlich ein eigenes Datasource hat und die Datenfelder natürlich auch. Auch werden die Felder editierbar, wenn man ein Doppelklick auf das Grid mach oder ein entsprechendes Button drückt. Aber das ganze ist unanhängig von meinem Problem.

Andreas

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6200
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Alle Datensätze werden geändert

Beitrag von af0815 »

Luckner hat geschrieben:
Fr 6. Mai 2022, 10:55
Eine Änderung eines Feldes und das Abspeichern, bewirkt das alle Datensätze dieser Tabelle mit den selben Änderungen überschrieben werden. Was mich jetzt auch wundert, dass auch die Felder ID ebenfalls mit der aktl. ID beschrieben werden. als ob es eine Kopie des Datensatzes auf alle Sätze der Tabelle gemacht werden.
Das Verhalten ist nachvollziehbar, wenn die zugrundeliegende Query mit dem Primärschlüssel Probleme hat. Dein Edit/Post wird interen in Update/Delete/Insert umgewandelt. Wenn gerade beim Update oder Delete nicht ein vernünftiger Schlüssel gefunden wird (Sollte PK sein), sondern nur was geraten wird von der eingebauten SQL-Logik, dann kommt ein solcher Salat heraus.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Luckner
Beiträge: 88
Registriert: Sa 18. Jan 2020, 09:56
OS, Lazarus, FPC: Winux (L 2.2.0 FPC 3.2.2)
CPU-Target: Windows 64-Bit

Re: Alle Datensätze werden geändert

Beitrag von Luckner »

Hallo af0815,

danke für diesen Hinweis. Dannach habe ich mir die beiden Tabellen angeschaut (die eine hat ja funktioniert) und tatsächlich in der funktionierenden Tabelle gab es einen primery key.
Da ich unter Delphi in meinen Tabellen nie einen primery key benutze, bin ich von der Auswirkung sehr überrascht. Werde jetzt auch unter Delphi damit rumexperimentieren.

Viellen Dank und Gruß, Andreas

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6200
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Alle Datensätze werden geändert

Beitrag von af0815 »

Generell ist es so, das man am besten nicht den internen SQL-Solver beanspruchen sollte, das der errät was man will/braucht. Delphi hat dort sicher mehr Erfahrung drinnen (auch über die legendäre BDE). Genaugenommen hängt es von stabilen Design in der Software ab. Da sollte man ganz einfach ausformulieren was man will und eine Tabelle ohne PK ist ein No-Go ausser einem Fall, in einer M:N Tabelle geht es auch ohne.

Das sind Erfahrungswerte. Woher bekommt man gute Erfahrung - natürlich von schlechter Erfahrung die man gemacht hat :mrgreen:

Kurzum, Delphi kann einem mal helfen, ohne das man es weis. UND Lazarus ist KEIN Delphi !! Es ist in (zu)vielen Sachen Sourcekompatibel aber nicht mehr. (Ich hasse es, wenn die Blödheiten von Delphi als - nicht als Bug sondern als Kompatibilität bezeichnet werden)
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

charlytango
Beiträge: 843
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: Alle Datensätze werden geändert

Beitrag von charlytango »

Luckner hat geschrieben:
Fr 6. Mai 2022, 18:54
Da ich unter Delphi in meinen Tabellen nie einen primery key benutze, bin ich von der Auswirkung sehr überrascht.
Ouuutch
af0815 hat geschrieben:
Fr 6. Mai 2022, 20:45
eine Tabelle ohne PK ist ein No-Go ausser einem Fall, in einer M:N Tabelle geht es auch ohne.
Tabelle ohne Primary Key geht gar nicht -- war eigentlich auch schon unter D7 obsolet und geht auch gar nicht wenn man eine Datenbank auch als solche benutzen will/muss (also mit Triggern, Views, Stored Procedures etc). Ist aus meiner Sicht einfach mangelhaftes DB-Design.

Früher gab es gelegentlich Probleme mit der Eindeutigkeit, aber heute ist das Session-Management verlässlich genug um sich darauf verlassen zu können. Ein ganzzahliges Feld mit Autoincrement reicht da völlig aus und um den Rest kümmert sich die DB.

Es hat auch jede Datenbank eine sessionsichere Möglichkeit um die letzte erzeugte ID abzufragen wenn man sie zB als Fremdschlüssel in einer anderen Tabelle braucht.
Für SQLite ist das: SELECT last_insert_rowid()

Antworten