Hallo zusammen,
ich möchte in einem Thread eine TObjectlist in eine
MsSQL-Datenbank schreiben.
Folgende Voraussetzungen sind vorhanden:
- Die Liste wird während eines Messzyklus mit 10 Werten/Sekunde ergänzt
- Die Liste ist eine Threadsave Kopie der eigentlichen Messliste
- In der Liste sind immer nur die Werte, die noch nicht in DB gesichert wurden
- Im Normalfall reicht Zeit aus um Daten immer gleich in DB zu schreiben
Jetzt soll aber zusätzlich sichergestellt werden, dass Daten auch dann weggeschrieben werden, wenn die Datenbankverbindung Unterbrechungen aufweist. Natürlich erst dann, wenn Verbindung wieder da.
Hier mein bisheriger Code.
Delphi-Quellcode:
procedure TThrSaveCalForce.Execute;
var
lstCopy, lstTmp: TList;
i, iLast: Integer;
Values: TCalForce;
begin
inherited;
FStatus := FormatDateTime('
ss.zzz', now) + '
Execute Start';
Synchronize(syncStatusEvent);
CoInitialize(
nil);
iLast := 0;
lstCopy := TList.Create;
dbQuery.Close;
try
while not (Terminated)
do
begin
// Noch nicht bearbeitete Daten in Temporäre Liste kopieren
try
System.TMonitor.Enter(lstCalForceProc);
Values := TCalForce.Create;
for i := iLast
to lstCalForceProc.Count - 1
do
begin
Values := lstCalForceProc.Items[i];
lstCopy.Add(Values);
end;
iLast := i + 1;
finally
System.TMonitor.Exit(lstCalForceProc);
end;
if lstCopy.Count > 0
then
begin
// Kopierte Daten abhandeln (z.B. in DB speichern) und Liste wieder löschen
try
dbQuery.Open;
if dbQuery.Active
then
begin
while lstCopy.Count > 0
do
begin
Values := lstCopy.Items[0];
if (Values.Art <> '
')
then
begin
dbQuery.Insert;
dbQuery.FieldByName('
CalReportID').Value := FReportID;
dbQuery.FieldByName('
Fact').Value := Values.Fact;
dbQuery.FieldByName('
FTarget').Value := Values.Ftarget;
dbQuery.FieldByName('
Art').Value := Values.Art;
dbQuery.FieldByName('
Temperatur').Value := Values.Temperatur;
dbQuery.FieldByName('
Humidity').Value := Values.Humidity;
dbQuery.FieldByName('
ServOrt').Value := FServOrt;
dbQuery.FieldByName('
ErstUserID').Value := FUserID;
dbQuery.FieldByName('
ErstDat').Value := Values.ErstDat;
dbQuery.Post;
FStatus := format('
RepID = %d, Force = %6.2fN, Temp = %5.2f°C', [FReportID, Values.Fact, Values.Temperatur]);
Synchronize(syncStatusEvent);
OutputDebugString(pChar(FStatus));
end;
lstCopy.Delete(0);
// gepeicherten Satz in lstCopy löschen
end;
end;
finally
dbQuery.Close;
end;
end;
Sleep(100);
end;
finally
lstCopy.Free;
end;
IsRunning := false;
end;
Meine Fragen:
- Wie stelle ich schnellstmöglich fest, ob eine Verbindung besteht?
- Bietet ein Insert direkt per "INSERT INTO TabName VALUES (FReportID, Values.Fact, ...)" Vorteile?
- Wenn ja, bietet es Vorteile wenn ich alle Werte der Liste in ein Insert packe (Values (ListenWerte1), (ListenWerte2) ...). Unter Beachtung der maximal zulässigen Anzahl (1000)?
- Muss nach einem Unterbruch die Connection manuell geöffnet werden oder öfnnet die sich automatisch mit dem dbQuery.Open?
Ich könnte das jetzt ausprobieren, aber meine Erfahrung ist, dass manches beim Probieren funktioniert, aber trotzdem nicht sauber ist und irgendwann schief geht. Deshalb wäre ich für Ratschläge dankbar
Grüße
Gerd