![]() |
SQL-Datei parsen und Comments löschen
Hallo,
ich bin gerade dabei eine Umgebung zu basteln zum entwickeln von MSSQL proceduren. Nun bin ich dabei den Parser zu bauen der zuerst mal zum internen arbeiten alle Comments durch Spaces ersetzt. Das ist meine Aktuelle Parser procedure (z.Z. und zum Testen ersetzt sie Strings durch $ und comments durch ?):
Delphi-Quellcode:
Zum testen habe ich diesen Codeschnipsel erstellt:
procedure Parse;
var Line:String; Y,X,Z,Token,Flag:Integer; begin FScanBuffer.Clear; FScanBuffer.Assign(FEditBuffer); Flag:=0; for Y:=0 to FScanBuffer.Count-1 do begin Line:=FScanBuffer[Y]; for X:=1 to Length(Line) do begin Token:=0; if Copy(Line,X,1) = #039 then Token:=1 else if Copy(Line,X,2) = '/*' then Token:=2 else if Copy(Line,X,2) = '--' then Token:=3 else if Copy(Line,X,2) = '*/' then Token:=4; case Token of 1: begin if (Flag <> 2) AND (Flag <> 3) then if Flag = 1 then Flag:=5 else Flag:=1; end; 2: begin if Flag <> 1 then Flag:=2; end; 3: begin if (Flag <> 1) AND (Flag <> 2) then Flag:=3; end; 4: begin if Flag = 2then Flag:=4; end; end; case Flag of 1: begin Line[X]:='$'; end; 2: begin Line[X]:='?'; end; 3: begin Flag:=0; for Z:=X to Length(Line) do Line[Z]:='?'; end; 4: begin Flag:=0; for Z:=X to X+2 do Line[Z]:='?'; end; 5: begin Flag:=0; Line[X]:='$'; end; end; end; FScanBuffer[Y]:=Line; end; FScanBuffer.SaveToFile('C:\test.txt'); end;
SQL-Code:
Und es kommt auch wie erwartet das als Ergebnis raus:
/*
--> comment block <-- */ SET @Tmp = '/* -- Test -- */' /* comment */ ; -- comment -- test comment SET @Tmp = '<-->'; -- comment's & comment's /* SET @Tmp = '*//*'; -- */
Code:
Nur mein Problem ist das das ganze bei großen Dateien sehr inperformant wird, hatte auch schon mehrere Versuche mit dem Parser das ist jetzt der Xte der auch wohl so funzt wie er soll nur sehr langsam.
??
?????? ?????????? ???????? ?????? ?? SET @Tmp = $$$$$$$$$$$$$$$$$$ ??????????????; ?????????? ??????????????? SET @Tmp = $$$$$$; ??????????????????????????? SET @Tmp = $$$$$$; ????? Deswegen hoffe ich auch euch, das wer eine bessere Idee hat jenes zu lösen, den ich hab keine mehr :( Grüße, Daniel P.s.: Das ist mein erster Parser dieser größe den ich entwickle deswegen stelle ich mich wohl zu blöd an ;) |
Re: SQL-Datei parsen und Comments löschen
Hin- und herkopieren von Strings ist immer sehr zeitintensiv.
Versuche das Kopieren von Strings wann immer es geht zu vermeiden. Du hast doch am Anfang den String - lese Zeichen für Zeichen und lass Befehle wie Line := Buffer[y] weg. |
Re: SQL-Datei parsen und Comments löschen
Hi bttb930,
also die Zeile aus der String Liste in Line zu übertragen ist denke ich mal das kleinste Übel daran liegt es nicht! Alles was zwischen Line:=FScanBuffer[Y]; und FScanBuffer[Y]:=Line; steht ist das Zeitaufwendige. |
Re: SQL-Datei parsen und Comments löschen
wir haben hier ein tool mit dem man geschwindigkeitsanalysen machen kann. schick doch mal den quellcode und eine demodatei und ich jag das mal durch. dann sieht man welche zeile wie lange braucht.
|
Re: SQL-Datei parsen und Comments löschen
aber ich habs mir nochmal angesehen - ich wette mit dir, dass das zeitaufwändige das hin- und herkopieren des strings ist. garantiert!
|
Re: SQL-Datei parsen und Comments löschen
Liste der Anhänge anzeigen (Anzahl: 1)
Ich hab mal schnell eine Test-Anwendung zusammen geschustert, kannst ja mal schaun.
|
Re: SQL-Datei parsen und Comments löschen
Also ein Hauptfehler deiner Procedure Parse scheint mir der fehlende Übergabeparamter zu sein.
==> nicht wiederverwendbar. hier mal meine Version zum "Putzen" von SQL-Anweisungen. (kann zwar nur einzeilige Kommentare entfernen, ist aber recht schnell)
Delphi-Quellcode:
{**************************************************************************
* NAME: CleanSqlStrings * DESC: entferne Kommentarzeilen aus TStrings * PARAMS: [-] * CREATED: 28-08-2003/shmia *************************************************************************} procedure CleanSqlStrings(SQL:TStrings); var s : string; i : Integer; begin Assert(Assigned(SQL)); for i := SQL.Count-1 downto 0 do begin s := SQL[i]; if Length(s) >= 2 then begin SetLength(s, 2); if (s = '--') or (s='//') then // Kommentarzeile entfernen SQL.Delete(i); end; end; end; |
Re: SQL-Datei parsen und Comments löschen
Liste der Anhänge anzeigen (Anzahl: 1)
okay, hier das ergebnis:
Die Zeile Memo2.Lines.Assign(FScanBuffer); benötigt 89,9% der Laufzeit. FScanBuffer.Assign(Memo1.Lines); benötigt noch 6,90%. Ich habe den Memo-Inhalt dazu auf ca. 6000 Zeilen erweitert. Siehe Bild. |
Re: SQL-Datei parsen und Comments löschen
@shmia
Das soll jetzt nicht böse klingen oder so aber das hat so gar nichts mit meinem Problem zu tun, bei mir geht es nicht um SQL Anweisungen sondern um MSSQL Stored Procedures. Nebenbei würde deine Procedure mir eine ganze Zeile rauskanten wenn dort ein Single-Line-Comment drin ist (so wie ich das verstehe nur wenn es am Anfang ist, was es ja nicht immer tut) ;) Und wozu soll ich meinem Parse ein Parameter übergeben? Das ist doch gar nicht von nöten, da es normalerweise in einer klasse steckt, schau dir mal bitte die Test-Anwendung an, bze den Source davon! Programmiertechnisch ist das kein Problem sondern eher eines auf der Logischen Ebene den Source durch zu Parsen ;) |
Re: SQL-Datei parsen und Comments löschen
@bttb930
Hmm okay... stimmt ich hab mal Memo2.Lines.Assign(FScanBuffer); duch Memo2.Text:=FScanBuffer.Text; getauscht geht etwas fixer aber irgendwie immer noch zu ruckelig... Es muss doch auch irgendwie Professioneller gehen so einen Parser zu schreiben, ich hab beim dem irgendwie so das Gefühl das der so... so klapperich und zu klobig ist, naja wie gesagt ich habe so etwas noch nie in der Form Programmiert, eher immer statische Parser. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:10 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