Hallo,
das man in einer echten Datenbank (Firebird) z. B. einen Datensatz nicht einfach nur einfügt sondern das ganze noch commiten muss, ist mir klar. Nun stellte ich aber gerade fest, dass ein Commit das ich abgesetzt habe, überhaupt nichts brachte. Ich hatte es einfach mal auskommentiert und trotzdem sind alle Tabellen die ich gefüllt habe ordnungsgemäß aufgefüllt worden. Auch ein paar "ALTER SEQUENCE "%s" RESTART WITH %d" die ich noch abgesetzt habe sind alle in der Datenbank angekommen. Nun frage ich mich, durch welchen Mechanismus ist das passiert?
Ich verwende eine TFDConnection-Komponente (namens "dbsAM_FB") und eine TFDTransaction-Komponente. In dieser ist das Options.AutCommit auf "False" gesetzt. Zum Einfügen der Datensätze verwende ich einen TFDQuery. Datensätze füge ich ein mit "qry_FB.ExecSQL(InsertSQL);".
Was bewirkt denn nun, dass ohne explizites "dbsAM_FB.Commit;" die Operationen (Einfügen und ALTER SEQUENCE) überhaupt nachhaltig sind?
Mal der etwas verkürzte Code, der die Daten per INSERT einträgt:
Delphi-Quellcode:
tbl_Pdx.TableName := TableNames[i];
tbl_Pdx.Open;
try
try
tbl_Pdx.First;
InsertFieldNames := '';
InsertFieldValues := '';
qry_FB.SQL.Clear;
{ Zuerst sammeln wir die Felder für das Insert-Statement. }
for k := 0 to Pred(tbl_Pdx.Fields.Count) do begin
FieldNameUpper := RenamedField(TableName, tbl_Pdx.Fields[k].FieldName);
if FieldNameUpper <> '' then begin
InsertFieldNames := InsertFieldNames + Format('"%s", ', [FieldNameUpper]);
InsertFieldValues := InsertFieldValues + Format(':%s, ', [FieldNameUpper]);
FieldNames[k] := FieldNameUpper;
end else begin
FieldNames[k] := '';
end;
end;
InsertFieldNames := Copy(InsertFieldNames, 1, Length(InsertFieldNames)-2);
InsertFieldValues := Copy(InsertFieldValues, 1, Length(InsertFieldValues)-2);
InsertSQL := Format('INSERT INTO "%s" (%s) VALUES (%s)', [TableName, InsertFieldNames, InsertFieldValues]);
qry_FB.SQL.Add(InsertSQL);
{ Jetzt sammeln wir die Felder für das "Params". }
for k := 0 to Pred(tbl_Pdx.Fields.Count) do begin
FieldNameUpper := tbl_Pdx.Fields[k].FieldName;
if FieldNameUpper <> '' then begin
FieldNameUpper := tbl_Pdx.Fields[k].FieldName;
qry_FB.Params.CreateParam(tbl_Pdx.Fields[k].DataType, FieldNameUpper, ptInput);
end;
end;
{ Alle Datensätze der Quelltabelle durchlaufen. }
for j := 0 to Pred(RecordCount) do begin
FMeter.CurrentValue := Succ(j);
Percent := (100 * j) div RecordCount;
for k := 0 to Pred(tbl_Pdx.Fields.Count) do begin
if FieldNames[k] = '' then Continue; // Ein Feld das in der Zieltabelle nicht mehr vorhanden ist überspringen
FieldNameMixed := tbl_Pdx.Fields[k].FieldName;
FieldNameUpper := FieldNames[k];
{ Nun die Werte je nach Datentyp übertragen von der Quelle ins Ziel }
case tbl_Pdx.Fields[k].DataType of
ftString :
if FieldNameMixed <> 'LoginPassword' then begin
qry_FB.ParamByName(FieldNameUpper).AsString := tbl_Pdx.FieldByName(FieldNameMixed).AsString;
end else begin
qry_FB.ParamByName(FieldNameUpper).AsString := GetStrHashBobJenkins(tbl_Pdx.FieldByName(FieldNameMixed).AsString);
end;
end; // case tbl_Pdx.Fields[k].DataType of
end; // for k := 0 to Pred(tbl_Pdx.Fields.Count) do
{ Wenn nur simuliert werden soll, keine Daten eintragen. }
if not chkSimulation.Checked then
qry_FB.ExecSQL(InsertSQL);
tbl_Pdx.Next;
{ Daten nur in größeren Brocken an die Datenbank übertragen. }
if (j mod 5000) = 0 then begin
if not chkSimulation.Checked then
dbsAM_FB.Commit;
end;
end; // for j := 0 to Pred(tbl_Pdx.RecordCount) do
if FStoped then Break; // Bricht die komplette Konvertierung sofort ab
FSkip := False;
finally
tbl_Pdx.Close;
end;
Danke im Voraus. Gruß, Markus