Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi AutoInc primary key Feld wird immer auf 0 gesetzt (https://www.delphipraxis.net/217097-autoinc-primary-key-feld-wird-immer-auf-0-gesetzt.html)

TurboMagic 25. Apr 2025 20:54

Datenbank: Firebird • Version: 5.0 • Zugriff über: FireDAC

AutoInc primary key Feld wird immer auf 0 gesetzt
 
Hallo,

ich habe eine DB Tabelle mit einem AutoInc Integer Feld Namens ID.
Das nutzt in Firebird einen Generator, dessen Wert ich eigentlich mittels
SQL Manager auf 4 gesetzt habe, da ich damit schon 4 Einträge in die Tabelle
gemacht hatte.

Nur wenn ich mit unten stehender Methode meinen neuen Text reinschreiben will
knallt es, weil er ID auf 0 statt 4 oder 5 setzen will.

Eigentlich hab' ich den Code analog zu Code für andere Tabellen der DB geschrieben
die auch AutoID Primärschlüssel haben und definitiv funktionieren. Hat jemand eine
Idee warum es da nicht klappt? Bzw. was kann ich noch testen?

Delphi-Quellcode:
procedure TMyTexts.SaveAddedText(Item: TMyText);
begin
  if not Assigned(FInsertQuery) then
  begin
    FInsertQuery := FDataSetFactory.GetDataSet(true);
    // Relevant, damit FireDAC beim Append später nicht wegen dem noch leeren
    // Primärschlüssel meckert.
    FInsertQuery.UpdateOptions.AutoIncFields := 'ID';
  end;

  FInsertQuery.Open('select ID, TEXT from MY_TEXTS');
  FInsertQuery.Append;
  FInsertQuery.FieldByName('TEXT').AsString := Item.Text;
  FInsertQuery.Post;

  Item.ID := FInsertQuery.FieldByName('ID').AsInteger;
end;

DaCoda 26. Apr 2025 19:46

AW: AutoInc primary key Feld wird immer auf 0 gesetzt
 
Also wenn dein Feld "ID" ein AutoIncrement - Feld ist und ich das nicht falsch verstanden habe, dann sollte das so reichen:


Code:
procedure TMyTexts.SaveAddedText(Item: TMyText);
begin
  FInsertQuery.Open('SELECT TEXT FROM MY_TEXTS');
  FInsertQuery.Insert;
  FInsertQuery.FieldByName('TEXT').AsString := Item.Text;
  FInsertQuery.Post;
  FInsertQuery.Close;
end;

TurboMagic 26. Apr 2025 19:50

AW: AutoInc primary key Feld wird immer auf 0 gesetzt
 
Danke für die Info!
Werde das baldmöglichst testen.
Du benutzt also statt Append Insert wenn ich das richtig sehe und lässt diese
AutoInc Felddefinition weg.

DaCoda 26. Apr 2025 20:02

AW: AutoInc primary key Feld wird immer auf 0 gesetzt
 
Das Insert ist einfach "gewohnheit", dein Insert geht genau so.

Der Unterschied besteht darin , dass Du mit append einfach einen neuen Eintrag am Ende der Liste hinzufügst. Mit insert(position, eintrag) kannst Du einen neuen Eintrag genau an der gewünschten Position erstellen. Ohne Positionsangabe ist ein insert praktisch ein append :-)

Entscheidend bei meinem vorherigen Posting ist einfach das du ein AutoInc-Feld nicht ausfüllen musst, das macht die Datenbank alleine.

himitsu 26. Apr 2025 20:05

AW: AutoInc primary key Feld wird immer auf 0 gesetzt
 
Normal sollte doch FireDAC auch nur ein INSERT-Statement mit den gefüllten Feldern generieren?
Felder, welche nicht im Statement drin stehen, werden serverseitig via Default/AutoInc gefüllt.

Im Grunde halte ich es eigentlich für einen gewaltigen Bug, dass bei Default/AutoInc-Feldern das Required im TField gesetzt wird, denn es ist eben nicht "wirklich" required (clientseitig).

Bei FireDAC kann man bestimmt auch deaktivieren, dass Required gesetzt wird.
Required prüft lokal, im BeforePost, aber es wird ja eh nochtmal serverseitig geprüft.

Keine Ahnung, was AutoIncFields überhaupt macht.
Wir nutzen eine abgeleitete pgDAC-Klasse, wo im AfterInsert über ein SELECT vom Server die Default/AutoInc-Werte geholt und in die Fields kopiert werden.
* einmal knallt es so bei Required-Check nicht
* und außerdem sieht man bereits vor dem Post (im Edit/Grid), was überall drin steht (auch das, was eigentlich erst beim Post in der DB gefüllt würde, abgesehn von BeforeInsertTriggern)

(das Einzige, womit man klarkommen muß, wird dann doch nicht gepostet, sondern verworfen, dann entstehen Lücken)

TurboMagic 26. Apr 2025 20:19

AW: AutoInc primary key Feld wird immer auf 0 gesetzt
 
Zitat:

Zitat von DaCoda (Beitrag 1548288)
Das Insert ist einfach "gewohnheit", dein Insert geht genau so.

Der Unterschied besteht darin , dass Du mit append einfach einen neuen Eintrag am Ende der Liste hinzufügst. Mit insert(position, eintrag) kannst Du einen neuen Eintrag genau an der gewünschten Position erstellen. Ohne Positionsangabe ist ein insert praktisch ein append :-)

Entscheidend bei meinem vorherigen Posting ist einfach das du ein AutoInc-Feld nicht ausfüllen musst, das macht die Datenbank alleine.

Nach meinem Test glaube ich dir das nur leider nicht mehr.
Ich bekomme eine EDatabaseError exception:
Im Projekt MyTest.exe ist eine Exception der Klasse EDatabaseError mit der Meldung 'Feld 'ID' muss einen Wert haben' aufgetreten.

:-(

fred42 26. Apr 2025 21:19

AW: AutoInc primary key Feld wird immer auf 0 gesetzt
 
Hallo,

in den Datenzugriffskomponenten (FDQuery bzw. FDTable) bei 'UpdateOptions' die entsprechenden
Eigenschaften angeben.

GeneratorName
Keyfields

sollte funktionieren.
Gruß

himitsu 27. Apr 2025 08:01

AW: AutoInc primary key Feld wird immer auf 0 gesetzt
 
Dass es in #2 geht, ist verständlich, da dort die Komponente deine ID-Spalte garnicht kennt, ihr Required somit nie beachtet und weil sie nie im generierten Statement vorkommen kann, sie immer von der DB mit dem Default (AutoInc) gefüllt wird,
aber da Firebird auch ein RETURNING kennt, weil du ja dennoch die ID wissen wolltest ...

SQL-Code:
  FInsertQuery.SQL.Text := 'insert into MY_TEXTS (TEXT) values (:TEXT) returning ID';
  FInsertQuery.ParamByName('TEXT').AsString := Item.Text;
  FInsertQuery.Open;
  Item.ID := FInsertQuery.FieldByName('ID').AsInteger;
  FInsertQuery.Close;

Olli73 27. Apr 2025 10:35

AW: AutoInc primary key Feld wird immer auf 0 gesetzt
 
Zitat:

Zitat von TurboMagic (Beitrag 1548278)
Hallo,

ich habe eine DB Tabelle mit einem AutoInc Integer Feld Namens ID.
Das nutzt in Firebird einen Generator, dessen Wert ich eigentlich mittels
SQL Manager auf 4 gesetzt habe, da ich damit schon 4 Einträge in die Tabelle
gemacht hatte.

Nur wenn ich mit unten stehender Methode meinen neuen Text reinschreiben will
knallt es, weil er ID auf 0 statt 4 oder 5 setzen will.

Eigentlich hab' ich den Code analog zu Code für andere Tabellen der DB geschrieben
die auch AutoID Primärschlüssel haben und definitiv funktionieren. Hat jemand eine
Idee warum es da nicht klappt? Bzw. was kann ich noch testen?

Delphi-Quellcode:
procedure TMyTexts.SaveAddedText(Item: TMyText);
begin
  if not Assigned(FInsertQuery) then
  begin
    FInsertQuery := FDataSetFactory.GetDataSet(true);
    // Relevant, damit FireDAC beim Append später nicht wegen dem noch leeren
    // Primärschlüssel meckert.
    FInsertQuery.UpdateOptions.AutoIncFields := 'ID';
  end;

  FInsertQuery.Open('select ID, TEXT from MY_TEXTS');
  FInsertQuery.Append;
  FInsertQuery.FieldByName('TEXT').AsString := Item.Text;
  FInsertQuery.Post;

  Item.ID := FInsertQuery.FieldByName('ID').AsInteger;
end;

Eigentlich fehlt hier nur ein RefreshRecord nach dem Post bzw. die Einstellung, dass das automatisch/immer gemacht wird:

https://docwiki.embarcadero.com/Libr...ns.RefreshMode

TurboMagic 27. Apr 2025 15:39

AW: AutoInc primary key Feld wird immer auf 0 gesetzt
 
Hallo,

nach Angabe des Generators und setzen des richtigen Startwertes für diesen in der DB funktioniert es jetzt.
Danke für alle Tipps!


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:48 Uhr.
Seite 1 von 2  1 2      

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-2025 by Thomas Breitkreuz