Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Select-Query auf MS-SQL-Server - nicht genügend Speicher (https://www.delphipraxis.net/140941-select-query-auf-ms-sql-server-nicht-genuegend-speicher.html)

windi 29. Sep 2009 11:19

Datenbank: MS-SQL-Server • Version: 2005 • Zugriff über: ADO

Select-Query auf MS-SQL-Server - nicht genügend Speicher
 
Hallo Leute,

habe folgendes Problem: In meinen Programm versuche ich über eine ADOConnection + ADOQuery eine SELECT-Abfrage auf einen MS-SQL-Server auszuführen:

SELECT MAX(protRecord_ID) FROM [WeldMeasureProt_T] WHERE [timerName]='R1SK1' AND [progNo]=146

(Die Daten in der WHERE-Klausel sind nur Beispiele) Diese Abfrage (und viele weitere) werden zyklisch immer wieder aufgerufen. Nach einiger Zeit bekomme ich jedoch eine Exception wenn ich die ADOQuery aktivieren möchte: "1240640 - Für diesen Vorgang ist nicht genügend Speicher verfügbar" Nach einiger Zeit kommt zusätzlich noch die Meldung: "Zugriffsverletzung bei Adresse 7C911F6E im Modul 'ntdll.dll'. Lesen von Adresse 000000004". Danach ist das Programm abgeschmiert.

Die SQL-Abfragen werden dabei in Threads ausgeführt. Hintergrund: Meine Programm kommuniziert mit einer SPS und empfängt zyklisch Meldungen. Diese müssen mit anderen Informationen aus verschiedenen Tabellen der SQL-Datenbank verknüpft und in eine andere Tabelle geschrieben werden. Anfangs hatte ich eine zyklische Arbeitsweise verwendet - leider kam es hier zu nicht akzeptablen Verzögerungen beim der Datenbankabfrage (teilweise 5s für eine SELECT-Query!) Deshalb habe ich die Informationen der SPS einem Thread übergeben, der ADOConnection und ADOQuery selbst erzeugt und nach der Abarbeitung auch wieder frei gibt. (Ich weiss die Beschreibung ist nicht so toll aber der Quellcode ist zu groß um diesen hier zu posten)

Die Fehlermeldung mit dem nicht genügend Speicher ist ja ein Indiz, nur wenn ich mir im Taskmanager den Speicherverbrauch meines Programmes anschau, dann ist der noch "normal" - also ca. 32MB - mal bissel mehr, mal bissel weniger - ich glaube also nicht dass es ein Speicherleak ist - habs auch mal mit Eurekalog getestet - das Programm hat keine Fehler gebacht.

Vielleicht hat ja schon mal jemand von euch mit einem solchen Problem zu kämpfen gehabt oder zumindest ne Erklärung für die Fehlermeldungen? Hab schon gegoogelt - nur nichts zufriedenstellendes gefunden.

Bin für jede Hilfe dankbar!

Windi

mkinzler 29. Sep 2009 11:30

Re: Select-Query auf MS-SQL-Server - nicht genügend Speicher
 
Werden die Abfragen dynamisch erzeugt oder Abfragen bestückt?
Parametrisierte Abfragen?

windi 29. Sep 2009 11:35

Re: Select-Query auf MS-SQL-Server - nicht genügend Speicher
 
Die Abfragen werden dynamisch erstellt:

Delphi-Quellcode:
FBOS6000_DB.DoSelectQuery('SELECT MAX(protRecord_ID) ' +
                            'FROM [WeldMeasureProt_T] ' +
                           'WHERE [timerName]=''' + FWeldingControl.Name + ''' AND ' +
                                 '[progNo]=' + IntToStr(FRobotSpot.WeldingProgNo));
Die Abfrage in der aufgerufenen Prozedur sieht folgendermaßen aus:

Delphi-Quellcode:
function TADODatabase.DoSelectQuery(Query: String): Boolean;
var StartTime: Double;
 begin
  if (ADOConnection.Connected) then
   begin
    StartTime := Now;
    try
     ADOQuery.Active := False;

     ADOQuery.SQL.Clear;
     ADOQuery.SQL.Add(Query);
     ADOQuery.Active := True;
     ADOQuery.First;
     Result := True;
    except
     on E: Exception do
      begin
       ShowErrorMessage('SQL Fehler in: "' + Query + '" auf ' + ServerName
                        + ' Grund: ' + IntToStr(E.HelpContext) + ' "' + E.Message + '"');
       Result := False;
      end;
    end;
    FQueryActivity.NewQueryExecution(Query, Now - StartTime);
   end
  else
   Result := False;
 end;

hoika 30. Sep 2009 16:52

Re: Select-Query auf MS-SQL-Server - nicht genügend Speicher
 
Hallo,

kann es sein, dass dem SQL-Server der Speicher ausgeht ?
Werden alle Queries auch wieder geschlossen ?

Das

Query.Active:= False

verstehe ich eh nicht (klar verstehe ich es, aber wieso wird das immer so geschrieben ?)

Ich mache es immer

Delphi-Quellcode:
Query.Open;
try
finally
  Query.Close;
end;
Ausserdem würde ich parametrisierte Queries benutzen,
für jede verschiedene Abfrage genau eine.
SP's gehen natürlich auch.


Heiko

Muchacho 9. Okt 2009 17:45

Re: Select-Query auf MS-SQL-Server - nicht genügend Speicher
 
Hi

Ich würde die MsSQL Log Datei überprüfen, ob Sie nicht zu groß
ist und notfalls diese auch verkleinern (z.B. auf 100 MB).

Vielleicht hilft das.

Muchacho

Bernhard Geyer 9. Okt 2009 17:53

Re: Select-Query auf MS-SQL-Server - nicht genügend Speicher
 
Wird das Connection-Objekt auch im Thread erstellt?
Ist der SQL Server Full Patched?

alzaimar 9. Okt 2009 18:59

Re: Select-Query auf MS-SQL-Server - nicht genügend Speicher
 
Hi

Ich bin bei solchen Sachen immer Konservativ und erzeuge die ADO-Dingens nur 1x. Gleichzeitig verwende ich einen Workerthread, der also permanent im Hintergrund läuft. Dieser nimmt Jobs (z.b. deine SELECT-Teile) entgegen, arbeitet sie sequenziell ab und übergibt die Ergebnisse.

Ich hab einfach kein gutes Gefühl bei einem 'ConnectionPool'-Mechanismus, wie ihn ADO verwendet und ich diesen Pool mit ständigen Create/Destroy-Aufrufen arg strapaziere. Ich würde wetten, mit o.g. Strategie tritt das Problem einfach nicht mehr auf.

windi 15. Okt 2009 16:51

Re: Select-Query auf MS-SQL-Server - nicht genügend Speicher
 
Hi!

Als erstes vielen Dank für die vielen Antworten. So recht hat nur leider nix geholfen. Anscheinend ist es wirklich so, dass dem Server die Puste ausgeht. Ich habe jetzt unseren Kunden soweit, dass ich auf einen Großteil der Abfragen verzichten kann und nur noch eine Workerthread verwende. Mitlerweile stellt sich aber ein neues Problem heraus. Von der ADOConnection bekomme ich bei einem INSERT-Befehl die Fehlermeldung "Zugriffsverletzung bei Adresse 77585D57 in Modul 'ole32.dll'. Lesen von Adresse 46147752" Dies tritt aber nur seeehr selten auf: 1 - 2 mal am Tag bei ca. 50.000 - 100.000 INSERT-Querys am Tag. Danach geht im Regelfall gar nix mehr. Also hab trenne ich in meiner Not die Datenbankverbindung, baue Sie danach wieder auf und führe die Abfrage nochmals durch. Dabei zeigt sich folgendes Fehlerbild (Auszug aus einer Logdatei):

2009.10.15 16:00:38: SQL Fehler in: "INSERT INTO [PQ25_BDE].[dbo].[PQ25WeldingPoints_T] ([TeileID] ,[dateTime] ,[timerName] ,[progNo] ,[WeldingError] ,[robSinkingDeep] ,[robSinkingDeepIO]) VALUES (16944, '16:00:38:062 15.10.2009', 'R7SK1', 31, 0, 1.01999998092651, 1)"
auf Grund: 0 "Zugriffsverletzung bei Adresse 77585D57 in Modul 'ole32.dll'. Lesen von Adresse 46147752"
2009.10.15 16:00:38: Fehler in der ADO-Verbindung. Verbindung wird getrennt und neu aufgebaut ...
2009.10.15 16:00:38: Verbindung wieder hergestellt, Abfrage wird erneut ausgeführt ...
2009.10.15 16:00:38: SQL Fehler in: "INSERT INTO [PQ25_BDE].[dbo].[PQ25WeldingPoints_T] ([TeileID] ,[dateTime] ,[timerName] ,[progNo] ,[WeldingError] ,[robSinkingDeep] ,[robSinkingDeepIO]) VALUES (16944, '16:00:38:062 15.10.2009', 'R7SK1', 31, 0, 1.01999998092651, 1)"
auf Grund: 0 "OLE-Fehler 800A0E7D"
2009.10.15 16:00:39: SQL Fehler in: "SELECT [protRecord_ID], [WeldingError] FROM [dbo].[PQ25WeldingPoints_T] WHERE [TeileID]=16944 AND [timerName]='R6SK1' AND [progNo]=28"
auf Grund: 0 "Stack-Überlauf"

Hat jemand vielleicht schon mal mit diesen Fehlermeldungen zu tun gehabt oder eventuell eine Idee was ich machen könnte?? Die Zugriffsverletzung in der ole32.dll muss ja einen Grund haben. Hab schon versucht nach dieser Fehlermeldung zu googeln, hab aber nich wirklich was passendes gefunden. :-(

p80286 15. Okt 2009 17:18

Re: Select-Query auf MS-SQL-Server - nicht genügend Speicher
 
@heiko

Zitat:

Hinweis:
Durch Aufrufen der Methode Open wird Active auf tTrue gesetzt; durch Aufruf der Methode Close wird Active auf false gesetzt.

das erklärt wohl das
Delphi-Quellcode:
Query.active:=true;
Ich nehme allerdings auch lieber open und close weil ich .active nicht über den Weg traue.

Gruß
K-H


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:20 Uhr.

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