![]() |
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:
Ich habe dafür auch eine Testanwendung erstellt.
FDQuery4.CopyDataSet(FDQuery3, [coRestart, coAppend, coEdit]);
Zum testen habe ich eine DB mit vier gleiche Tabellen angelegt. Alle vier Querys mit dem gleichen Inhalt
Code:
natürlich jeweils die andere Tabelle.
SELECT * FROM KONTAKTE
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 |
AW: FireDac CopyDataSet kopiert nicht den PK
Wie sieht der Trigger aus? Wirkt der Generator wirklich nur bei leeren Feldern?
|
AW: FireDac CopyDataSet kopiert nicht den PK
Zitat:
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 |
AW: FireDac CopyDataSet kopiert nicht den PK
In deinem Projekt fehlen die Query-Komponenten.
|
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.
|
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:
Gruß Kostas
FDQuery2.CopyDataSet(FDQuery1, [coStructure, coRestart, coAppend, coEdit]);
[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. |
AW: FireDac CopyDataSet kopiert nicht den PK
Zitat:
|
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. |
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; |
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 |
AW: FireDac CopyDataSet kopiert nicht den PK
Zitat:
|
AW: FireDac CopyDataSet kopiert nicht den PK
Hallo Uwe,
ich konnte jetzt nachstellen das die Ursache wie du schon sagtest nicht CopyDataSet ist sondern FireDac und dessen Query. Ich habe in meinem Code nachgeschaut wo ich CopyDataSet verwende. Es ist immer so das ich ein DataSet über einen DataSnap Server bekomme und diesen in einer MemTable oder direkt verarbeite. Ich schreibe also nie über die Query in die DB. Deshalb hat es bis jetzt funktioniert. Dass die Query mein übergebener PK einfach ignoriert war mir nicht klar. Ich habe all die Jahre IBO verwendet und da ist es nicht so. Wenn ich ein PK(AutoInc) Feld ein Wert übergebe, wird dieser auch zur Datenbank transportiert, ansonsten feuert er selbst den Generator unmittelbar vor dem Schrieben in die DB. Das war jetzt für mich eine sehr sehr wichtige Lehrstunde. Tausend Dank nochmals Uwe.
Delphi-Quellcode:
function TForm1.MyCopyDataSet(Qu,Zi:TFDQuery):Boolean;
var n:Integer; begin Qu.First; while not Qu.Eof do begin Zi.Insert; for n:=0 to Qu.FieldCount-1 do begin Zi.FieldByName(Qu.Fields[n].FieldName).value := Qu.Fields[n].value; end; Zi.Post; Qu.next; end; result:=true; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:00 Uhr. |
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 by Thomas Breitkreuz