Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   FireDac CopyDataSet kopiert nicht den PK (https://www.delphipraxis.net/186107-firedac-copydataset-kopiert-nicht-den-pk.html)

Kostas 4. Aug 2015 09:48

Datenbank: Firebird • Version: 2.5 • Zugriff über: FireDac

FireDac CopyDataSet kopiert nicht den PK
 
Liste der Anhänge anzeigen (Anzahl: 4)
Hallo Zusammen,

Delphi XE8, FB2.5

CopyDataSet sollten eigentlich die Komplette Datenmänge kopieren.

Delphi-Quellcode:
FDQuery4.CopyDataSet(FDQuery3, [coRestart, coAppend, coEdit]);
Ich habe dafür auch eine Testanwendung erstellt.
Zum testen habe ich eine DB mit vier gleiche Tabellen angelegt.
Alle vier Querys mit dem gleichen Inhalt
Code:
SELECT * FROM KONTAKTE
natürlich jeweils die andere Tabelle.

Beim ausführen von CopyDataSet werden alle Felder kopiert ausser das PK Field.
Genauer gesagt, im Grid wird sogar der PK richtig angezeigt, in der DB jedoch
wird der PK nicht übertragen und somit feuert der Trigger der den nächsten Generatorwert holt.

Ich habe übrigens auch alle andere CopyDataSetOptions ausprobiert, immer das gleiche Verhalten.
Hat jemand eine Idee?

Gruß Kostas

mkinzler 4. Aug 2015 09:58

AW: FireDac CopyDataSet kopiert nicht den PK
 
Wie sieht der Trigger aus? Wirkt der Generator wirklich nur bei leeren Feldern?

Kostas 4. Aug 2015 10:00

AW: FireDac CopyDataSet kopiert nicht den PK
 
Zitat:

Zitat von mkinzler (Beitrag 1310886)
Wie sieht der Trigger aus? Wirkt der Generator wirklich nur bei leeren Feldern?

ja, eigentlich schon.
Delphi-Quellcode:
CREATE OR ALTER trigger kontakte_bi for kontakte
active before insert position 0
as
begin
  if (new.kontaktid is null) then
    new.kontaktid = gen_id(gen_kontakte_id,1);
end

Uwe Raabe 4. Aug 2015 10:42

AW: FireDac CopyDataSet kopiert nicht den PK
 
In deinem Projekt fehlen die Query-Komponenten.

Uwe Raabe 4. Aug 2015 10:52

AW: FireDac CopyDataSet kopiert nicht den PK
 
CopyDataSet setzt bei einem AutoInc-Feld nur dann das IdentityInsert auf true, wenn coStructure mit übergeben wird. Andernfalls musst du das vor dem CopyDataSet selber machen, sonst hält FireDac den Wert für einen lokal erzeugten und lässt die DB den selbst generieren.

Kostas 4. Aug 2015 10:56

AW: FireDac CopyDataSet kopiert nicht den PK
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Uwe, in der Form sind alle vier Querys enthalten. Was könntest du meinen?

Auch coStructure hab ich versucht leider ohne Erfolg.
Delphi-Quellcode:
FDQuery2.CopyDataSet(FDQuery1, [coStructure, coRestart, coAppend, coEdit]);
Gruß Kostas

[Edit]
oh, muss ich revidieren. coStructure scheint zu funktionieren wenn der PK ein Integer ist.
Bei BigInt funktioniert es nicht. Ich habe es vorhin immer nur mit BigInt ausprobiert.

Uwe Raabe 4. Aug 2015 11:04

AW: FireDac CopyDataSet kopiert nicht den PK
 
Zitat:

Zitat von Kostas (Beitrag 1310904)
in der Form sind alle vier Querys enthalten.

In dem Download aber nicht.

Kostas 4. Aug 2015 11:11

AW: FireDac CopyDataSet kopiert nicht den PK
 
Liste der Anhänge anzeigen (Anzahl: 1)
Sorry Uwe,
ich habe das Zip mit allen Files angehängt.

[Edit] in dem aktuellen Projekt benötige ich leider BigInt.
Die PKs auf Integer setzt ist nicht möglich.
Eine Alternative ist natürlich dynamisch das SQL für UPDATE OR INSERT INTO
zu generieren und auf CopyDataSet zu verzichten.

Uwe Raabe 4. Aug 2015 13:08

AW: FireDac CopyDataSet kopiert nicht den PK
 
So sollte es sowohl mit Integer als auch BigInt gehen (auch ohne coStructure):

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  fld: TField;
begin
  fld := FDQuery2.FieldByName('KONTAKTID');
  PrepareAutoIncField(fld);
  FDQuery2.CopyDataSet(FDQuery1, [coRestart, coAppend, coEdit]);
  RestoreAutoIncField(fld);
  FDQuery2.refresh;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  fld: TField;
begin
  fld := FDQuery4.FieldByName('KONTAKTID');
  PrepareAutoIncField(fld);
  FDQuery4.CopyDataSet(FDQuery3, [coRestart, coAppend, coEdit]);
  RestoreAutoIncField(fld);
  FDQuery4.refresh;
end;

procedure TForm1.PrepareAutoIncField(AField: TField);
begin
  if AField is TFDAutoIncField then begin
    (AField as TFDAutoIncField).IdentityInsert := true;
  end
  else begin
    AField.AutoGenerateValue := TAutoRefreshFlag.arNone;
    AField.ProviderFlags := [pfInUpdate, pfInWhere, pfInKey];
  end;
end;

procedure TForm1.RestoreAutoIncField(AField: TField);
begin
  if AField is TFDAutoIncField then begin
    (AField as TFDAutoIncField).IdentityInsert := false;
  end
  else begin
    AField.AutoGenerateValue := TAutoRefreshFlag.arAutoInc;
    AField.ProviderFlags := [pfInWhere, pfInKey];
  end;
end;

Kostas 4. Aug 2015 14:00

AW: FireDac CopyDataSet kopiert nicht den PK
 
Tausend Dank Uwe,

so funktioniert es.

Ich habe in dem Projekt mehrere Stellen in denen ich CopyDataSet
nutze. Es ist bis jetzt nicht aufgefallen. Würdest du das als Bug
bezeichnen? Oder warum gibt es keine Option dieses Verhalten zu steuern? Zumindest habe ich jetzt verstanden dass das zusammenhängt
mit den AutoInc Feldern.

Gruß Kostas


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:08 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