![]() |
SQL Datenbank / Timeout
Hallo,
ich hoffe ihr könnt mir weiter helfen. Ich habe ein kleines Programm geschrieben, das Werte aus einer MSSQL-Datenbank liest, über diese einen Mittelwert bildet und diesen dann in einer anderen Tabelle abspeichert. Nun läuft das Programm anfangs recht gut, wird mit der Zeit aber immer langsamer und nach ca. 100 bis 150 Datensätzen bekomme ich die Fehlermeldung "Timeout abgelaufen". Wenn ich das Programm neu starte, ohne zu rebooten, kommt die Fehlermeldung schon nach ca. 15 Datensätzen. Die Datenbanken : Datenbank_A = Hier stehen alle Nummern der Datensätze (~500 Zeilen) Datenbank_B = Hier gibt es zur Nummer den Zeitraum (~2.000.000 Zeilen) Datenbank_C = Hier wird über den Zeitraum aus B der Mittelwert gebildet (~9.000.000) Datenbank_D = Hier wird das Ergebnis gespeichert Wie ihr sehen könnt sind die momentan bearbeiteten Datenbanken recht groß. Und hier nun der Quelltext:
Delphi-Quellcode:
procedure TForm1.BtnLOSClick(Sender: TObject);
Var DateStart, DateStop, j : String; M_Fin2ManTemp, M_HeaterT1, M_HeaterT3, M_PLCCW1, M_PLCCW2, M_SupBlwr2, M_SupBlwr3 : double; count, i : Integer; begin i := 0; j := IntToStr(Datenbank_A.RecordCount); Datenbank_A.First; while not Datenbank_A.Eof do begin Label1.Caption := 'Datensatz ' + IntToStr(i) + ' von ' + j; Form1.Repaint; with Datenbank_B do begin Close; CommandText := 'SELECT * FROM Datenbank_B' + ' WHERE Nummer = ' + '''' + Datenbank_A.FieldByName('Nummer').AsString + '''' + ' ORDER BY Date_Time'; Open; First; DateStart := FieldByName('Date_Time').AsString; Last; DateStop := FieldByName('Date_Time').AsString; end; M_Fin2ManTemp := 0; M_HeaterT1 := 0; M_HeaterT3 := 0; M_PLCCW1 := 0; M_PLCCW2 := 0; M_SupBlwr2 := 0; M_SupBlwr3 := 0; with Datenbank_C do begin Close; CommandText := 'SELECT * FROM Datenbank_C ' + ' WHERE Date_Time BETWEEN ' + '''' + DateStart + '''' + ' AND' + '''' + DateStop + ''''; Open; First; while not Datenbank_C.Eof do begin if FieldByName('Fin2ManTempFB').AsFloat <> NULL then M_Fin2ManTemp := M_Fin2ManTemp + FieldByName('Fin2ManTempFB').AsFloat else M_Fin2ManTemp := M_Fin2ManTemp + 0; if FieldByName('Heater T1 Gas Valve').AsFloat <> NULL then M_HeaterT1 := M_HeaterT1 + FieldByName('Heater T1 Gas Valve').AsFloat else M_HeaterT1 := M_HeaterT1 + 0; if FieldByName('Heater T3 Gas Valve').AsFloat <> NULL then M_HeaterT3 := M_HeaterT3 + FieldByName('Heater T3 Gas Valve').AsFloat else M_HeaterT3 := M_HeaterT3 + 0; if FieldByName('PLCCW1TarWG').AsFloat <> NULL then M_PLCCW1 := M_PLCCW1 + FieldByName('PLCCW1TarWG').AsFloat else M_PLCCW1 := M_PLCCW1 + 0; if FieldByName('PLCCW2TarWG').AsFloat <> NULL then M_PLCCW2 := M_PLCCW2 + FieldByName('PLCCW2TarWG').AsFloat else M_PLCCW2 := M_PLCCW2 + 0; if FieldByName('SupBlwr2\Speed').AsFloat <> NULL then M_SupBlwr2 := M_SupBlwr2 + FieldByName('SupBlwr2\Speed').AsFloat else M_SupBlwr2 := M_SupBlwr2 + 0; if FieldByName('SupBlwr3\Speed').AsFloat <> NULL then M_SupBlwr3 := M_SupBlwr3 + FieldByName('SupBlwr3\Speed').AsFloat else M_SupBlwr3 := M_SupBlwr3 + 0; Next; end; end; count := Datenbank_C.RecordCount; if count <> 0 then begin M_Fin2ManTemp := M_Fin2ManTemp / count; M_HeaterT1 := M_HeaterT1 / count; M_HeaterT3 := M_HeaterT3 / count; M_PLCCW1 := M_PLCCW1 / count; M_PLCCW2 := M_PLCCW2 / count; M_SupBlwr2 := M_SupBlwr2 / count; M_SupBlwr3 := M_SupBlwr3 / count; end; with Datenbank_D do begin Insert; Edit; FieldByName('Nummer').AsString := Datenbank_A.FieldByName('Nummer').AsString FieldByName('Fin2ManTempFB').AsFloat := M_Fin2ManTemp; FieldByName('Heater T1 Gas Valve').AsFloat := M_HeaterT1; FieldByName('Heater T3 Gas Valve').AsFloat := M_HeaterT3; FieldByName('PLCCW1TarWG').AsFloat := M_PLCCW1; FieldByName('PLCCW2TarWG').AsFloat := M_PLCCW2; FieldByName('SupBlwr2\Speed').AsFloat := M_SupBlwr2; FieldByName('SupBlwr3\Speed').AsFloat := M_SupBlwr3; Post; Next; end; Datenbank_A.Next; i := i + 1; end end; |
Re: SQL Datenbank / Timeout
Das was Du da machst, lässt mir die Haare zu Berge steigen :cyclops:
Du kannst den ganzen Spass mit einem einzigen SQL-Statement erledigen (dafür sind ja "richtige" DB's da), ohne das alles in Delphi machen zu müssen. Versuch es mal mit:
SQL-Code:
Gruß
INSERT INTO Datenbank_D
SELECT SUM(C.[Fin2ManTempFB] )/COALESCE(COUNT(C.*),1) , SUM(C.[Heater T1 Gas Valve])/COALESCE(COUNT(C.*),1) , SUM(C.[Heater T3 Gas Valve])/COALESCE(COUNT(C.*),1) , SUM(C.[PLCCW1TarWG] )/COALESCE(COUNT(C.*),1) , SUM(C.[PLCCW2TarWG] )/COALESCE(COUNT(C.*),1) , SUM(C.[SupBlwr2\Speed] )/COALESCE(COUNT(C.*),1) , SUM(C.[SupBlwr3\Speed] )/COALESCE(COUNT(C.*),1) FROM Datenbank_A A INNER JOIN Datenbank_B B ON B.Nummer = A.Nummer INNER JOIN Datenbank_C C ON C.Date_Time BETWEEN min(B.Date_Time) AND max(B.Date_Time) GROUP BY A.NUMMER |
Re: SQL Datenbank / Timeout
Hi Leuselator,
danke für deine Hilfe. Sicher gibt es mehrere Wege, dieses Problem zu lösen. Allerdings hilft mir dein SQL-Statement "nur" für dieses Problem. Mein Programm soll noch neben der Mittelwertbildung auch noch eine Integralbildung beinhalten. Und nun habe ich trotzdem noch das Problem mit dem Time-Out Fehler beim abfragen größerer Datenbanken. Nichts desto trotz habe ich deinen Code mal in den Query-Analyzer geworfen um zu schauen, wieviel schneller es damit ist und folgende Fehlermeldung erhalten.
Delphi-Quellcode:
Mit der Hilfe des Query Analyzers kann ich keine Fehler entdecken. Weder das COUNT noch das COALESCE erscheint mir fehlerhaft :?:
Server: Nachr.-Nr. 170, Schweregrad 15, Status 1, Zeile 2
Zeile 2: Falsche Syntax in der Nähe von '*'. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:41 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-2025 by Thomas Breitkreuz