Delphi-PRAXiS
Seite 4 von 4   « Erste     234   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Fehlermeldung "Zu wenig Arbeitsspeicher" (https://www.delphipraxis.net/118362-fehlermeldung-zu-wenig-arbeitsspeicher.html)

jim_raynor 7. Aug 2008 08:39

Re: Fehlermeldung "Zu wenig Arbeitsspeicher"
 
Zitat:

Zitat von Phoenix
Für mich gerade logische Erklärung:
Du benutzt ziemlich intensiv 'copy'. Das erzeugt eine String-Variable. Da Du das Ergebnis sofort verwendest und nirgends 'manuell' zwischenspeicherst, muss Delphi die Variable ja irgendwo hinpacken. Jedes einzelne Copy braucht also Speicher, der solange belegt wird, bis die Funktion beendet ist. (Kann auch sein, dass ich mich hier irre. Ich kenne die interna dafür nicht gut genug).

Ja, diese Erfahrung habe ich auch gemacht. Zumindestens in Delphi 7 ist es tatsächlich so, dass alle temporären Strings die in einer Prozedur anfallen erst am Ende freigegeben werden.

DerAndereMicha 7. Aug 2008 09:53

Re: Fehlermeldung "Zu wenig Arbeitsspeicher"
 
So, ich habe mir alles mal angeschaut und mich entschlossen bei meiner Logik zu bleiben, aber Eure Einwände mit einzubeziehen.

@nahpets: Deine Prozedur hat leider scheinbar auch einige Fehler, jedenfalls liefert Sie nicht immer ein korrektes Ergebis.
z.B. bei

SQL-Code:
       
Select * /* Daten
-- ,daten1
-- ,daten2
-- ,daten3 */ from
Aber es geht ja hier nicht um Deine Prozedur, sondern um meine ;-) Trotzdem Danke für Deine Anregungen.


Deine Anmerkungen hinsichtlich Oracle sind zwar richtig, aber in meinem Fall brauch ich das wohl nicht zu beachten, da ich nur mit dem MS-SQL-Server arbeite.

Das mit:

SQL-Code:
Select * from tabelle where sqlstring like '%/*%'
ist aber allerdings schon ein Problem. Ich denke aber ich kann das vernachlässigen, zumindest bis zur 1.Meldung eines Kunden, der nach diesem String selektieren möchte ;.)

Die Kommentare müssen raus, da sie beim Zugriff mit ADO unter gewissen Umständen zu Problemen führen und ich nicht weiß was mein Kunde in seine SQL-Skripte alles reinschreibt.


@DeddyH: Deine Prozedur funktioniert hervorragend, ist aber deutlich langsamer (bis zu 10x) als meine, sobald es sich um große SQL-Skripte mit vielen Zeilen handelt, ansonsten ist sie schneller.


@Alle
Ansonsten noch mal allen vielen Dank. Ich hoffe die Optimierungen (besonders die COPY-Problematik) haben geholfen und ich sehe den Fehler nie wieder in meinen Fehlerprotokollen.

Gruß
Micha

nahpets 7. Aug 2008 10:17

Re: Fehlermeldung "Zu wenig Arbeitsspeicher"
 
Hallo,
Zitat:

Zitat von DerAndereMicha
@nahpets: Deine Prozedur hat leider scheinbar auch einige Fehler, jedenfalls liefert Sie nicht immer ein korrektes Ergebis.
z.B. bei

SQL-Code:
       
Select * /* Daten
-- ,daten1
-- ,daten2
-- ,daten3 */ from

Ja, sie war nur so mal eben hingeschrieben, wenn zuerst die Kommentare der Form -- gelöscht werden, muss sie scheitern, da dann ein */-Ende weggeworfen wird. Daher mein verspäteter Einwand: Zeilenumbrüche einzubauen, erst die *-Kommentare wegzuwerfen und als "Rest" dann die -- Kommentare.

Zitat:

Zitat von DerAndereMicha
Das mit:

SQL-Code:
Select * from tabelle where sqlstring like '%/*%'
ist aber allerdings schon ein Problem.

Naja, ist schon weit hergeholt (eigentlich), da ich aber bei vielen Programmen die SQL's in einer Datenbanktabelle ablege und sie erst kurz vor der Verwendung im Programm einlese, ist das für mich zuweilen tatsächlich ein Problem, dafür kann ich aber beim Wechsel der Datenbank die SQL's in der Tabelle ändern und muss nicht an's Programm (und das hat durchaus was).

Bin ja nicht neugierig :wink:, aber wie sieht jetzt Deine Lösung aus?

Stephan

DerAndereMicha 7. Aug 2008 11:05

Re: Fehlermeldung "Zu wenig Arbeitsspeicher"
 
Hallo,

ich hab nichts weiter mehr geändert, nur die Reihenfolge der Blöcke vertauscht, die überflüssige IF-Anweisung raus und noch ein try/finaly dazu.

Delphi-Quellcode:
function DeleteCommentsNeu(const SQLLines:TStringList):Boolean;
var beg,en,i,Laenge : integer;
var Temp,begStr,enStr:String;
begin
  Laenge:=Length(SQLLines.Text);
  SQLLines.BeginUpdate;
  Try

   //Mehrzeile Kommentare
   Temp:=SQLLines.Text;
   while (pos('/*',Temp) <> 0) and
     (pos('*/',Temp)>pos('/*',Temp)) do
   begin
      beg:=pos('/*',Temp);
      en:=pos('*/',Temp)+2;

      begStr:=copy(Temp,1,beg-1);
      enStr:= copy(Temp,en,Length(Temp));

      Temp:=begStr+enStr;
   end;
   SQLLines.Text:=Temp;


   //Einzeilige Kommentare
   for i:= SQLLines.Count-1 downto 0 do
   Begin
      beg:=pos('--',SQLLines[i]);
      if beg <> 0 then
      Begin
        if beg=1 then SQLLines.Delete(i)
        else SQLLines[i]:=Copy(SQLLines[i],1,beg-1);
      end;
   end;

  Finally
    SQLLines.EndUpdate;
  End;
  Result:=Length(SQLLines.Text)<>Laenge;
end;
Gruß
Micha

nahpets 7. Aug 2008 11:20

Re: Fehlermeldung "Zu wenig Arbeitsspeicher"
 
Hallo,

einen hätt' ich noch, Du ermittelst die Beginn- und Endepositionen mehrfach, das kann bei großen Datenmengen schon ein bisserl dauern:

Delphi-Quellcode:
 //Mehrzeile Kommentare
   Temp := SQLLines.Text;
   beg := pos('/*',Temp);
   en  := pos('*/',Temp) + 2;
   while (beg <> 0) and (en > beg) do
   begin
      begStr := copy(Temp,1,beg - 1);
      enStr := copy(Temp,en,Length(Temp));
      Temp  := begStr + enStr;
      beg   := pos('/*',Temp);
      en    := pos('*/',Temp) + 2;
   end;
   SQLLines.Text := Temp;
Das könnte eventuell schneller werden.

Stephan

OldGrumpy 7. Aug 2008 11:50

Re: Fehlermeldung "Zu wenig Arbeitsspeicher"
 
Dazu fällt mir noch was ein, ich schreib mal Kommentare in den Code...

Zitat:

Zitat von nahpets
Delphi-Quellcode:
 //Mehrzeile Kommentare
   Temp := SQLLines.Text;
   beg := pos('/*',Temp);
   //wenn beg=0 kann man sich den Rest sparen
   en  := pos('*/',Temp) + 2;
   //mittels PosEx kann man hier auch zeit sparen (en muss hinter beg liegen, also erst ab Position en suchen
   while (beg <> 0) and (en &gt; beg) do
   begin
      begStr := copy(Temp,1,beg - 1);
      enStr := copy(Temp,en,Length(Temp));
      Temp  := begStr + enStr;
      //beg kann jetzt nicht mehr kleiner sein als begStr,
      //daher hier mit PosEx weitersuchen!
      beg   := pos('/*',Temp);
      en    := pos('*/',Temp) + 2;
   end;
   SQLLines.Text := Temp;


DerAndereMicha 7. Aug 2008 12:01

Re: Fehlermeldung "Zu wenig Arbeitsspeicher"
 
"beg" kann nicht 0 sein, daß wird doch schon in der WHILE-Bedingung abgefangen.

Das mit dem PosEx werde ich noch ändern, Danke für den Hinweis.

Gruß
Micha

OldGrumpy 7. Aug 2008 12:12

Re: Fehlermeldung "Zu wenig Arbeitsspeicher"
 
Du hast Recht, ich hatte mir nur das Snippet im letzten Post angeschaut, da ist die umfassende Whileschleife ja nicht mit drin, deswegen hab ichs übersehen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:57 Uhr.
Seite 4 von 4   « Erste     234   

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