phpbar.de logo

Mailinglisten-Archive

[php] SQL-Query zerlegen

[php] SQL-Query zerlegen

Matthias Spork hallo at matthiasspork.de
Mit Okt 18 00:02:46 CEST 2006


Danke Yannik!

die Idee mit dem durchlaufen des Strings in Verbindung mit den Klammern 
hat mir auf die Sprünge geholfen. Diese Schleife musste ich insg. 3 mal 
durchlaufen um nach WHERE, GROUP BY und JOIN zu suchen. Je nachdem was 
es gibt, muss der Query anders aufgebaut und die Suchfelder an die 
richtige Stelle geschrieben werden.

Viele Grüße
Matthias


Yannik Hampe schrieb:
> Matthias Spork wrote:
>   
>> Hallo,
>>
>> gerne würde ich hier nochmal meine Frage aufwerfen, sie aber etwas 
>> anders Formulieren:
>>
>> Ich suche ein Möglichkeit, mit der ich in ein beliebiges SQL-QUERY 
>> (welches auch Subselects enthält) weitere WHERE-Statements einfügen 
>> kann. Es würde mir schon reichen zu wissen, wie ich das _eigentliche_ 
>> WHERE in dem Query finden kann, falls eines vorhanden ist.
>> Hat jemand sowas schonmal gemacht?
>>     
> Sowas gemacht habe ich noch nie, aber SQL parsen hmm...
> WHERE beginnt ja schonmal logischerweise nach dem Schlüsselwort WHERE.
> Dann kommt ein boolischer Wert und dann ist die Wherebedingung zu
> Ende... Das problematischste dürfte es sein die Länge der WHERE
> Bedingung rauszufinden... Entweder du parst den String nach dem where
> richtig... Also mit anderen Worten gehst zeichenweise durch, zählst,
> wieviele Klammern geöffnet und geschlossen wurden usw. oder du überlegst
> dir einfach, womit eine WHERE-Anweisung abgeschlossen werden kann...:
> Aus der MySQL-Referenz. Je nach SQL-Server musst du das noch anpassen:
>
> SELECT
>     [ALL | DISTINCT | DISTINCTROW ]
>       [HIGH_PRIORITY]
>       [STRAIGHT_JOIN]
>       [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
>       [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
>     select_expr, ...
>     [FROM table_references
>     [WHERE where_condition]
>     [GROUP BY {col_name | expr | position}
>       [ASC | DESC], ... [WITH ROLLUP]]
>     [HAVING where_condition]
>     [ORDER BY {col_name | expr | position}
>       [ASC | DESC], ...]
>     [LIMIT {[offset,] row_count | row_count OFFSET offset}]
>     [PROCEDURE procedure_name(argument_list)]
>     [INTO OUTFILE 'file_name' export_options
>       | INTO DUMPFILE 'file_name'
>       | INTO @var_name [, @var_name]]
>     [FOR UPDATE | LOCK IN SHARE MODE]]
>
> Wenn ein WHERE vokommt, dann kommt danach also ein GROUP BY, ein HAVING,
> ein ORDER BY, ein LIMIT,..., oder ein Zeilenende.
> Du kannst also einfach mit strpos probieren, ob ein ORDER BY, dann ein
> HAVING usw. nach dem WHERE vorkommt und dann dir eben einen substring
> mit diesem Ende zu kopieren.
> Ein Prolem bleibt dabei:
> SELECT blabla WHERE somefield='LIMIT'
> und du hast ein Problem. Du musst in diesem Fall also auch noch prüfen,
> ob nicht schon in Anführungszeichen vorher ein Befehl kommt. Der muss
> natürlich nicht alleineig in den Anführungszeichen vorkommen, sondern
> auch sowas wie 'aaLIMITbb' kann vorkommen, also nicht einfach.
>
> Da musst du dir dann überlegen ob so eine Trickserei wirklich einfacher
> ist als Zeichenweise durchzugehen...
> $tmp ='';
> $inQuotes =false;
> $klammerlevel =0;
> for (zeichenweise durchgehen)
> {
>   //$c enthält das aktuelle Zeichen
>   if ($c =="'") $inQuotes =!$inQuotes;
>   elseif ($c =='(') ++$klammerlevel;
>   elseif ($c ==')') --$klammerlevel;
>   else $tmp .=$c;
>   if ($tmp endet mit einem der oben genannten schlüsselwörtern hinter WHERE)
>   {
>     //gefundenes Schlüsselwort entfernen und schon hast du den
> WHERE-string in $tmp
>   }
> }
> Das habe ich jetzt allerdings mal so ganz easy im Kopf direkt in
> Thunderbird gehackt und ich versuche niemanden zu erzählen, dass diese
> Funktion vollständig ist. Aber es sollte genug Denkansatz sein um dir
> bei deinem problem weiter zu helfen...
>   
>> Viele Grüße
>> Matthias
>>     
>
> Yannik
>   


php::bar PHP Wiki   -   Listenarchive