2011-01-17 6 views
2

Zunächst gestehe ich, ich bin nicht wirklich mit regulären Ausdrücken experimentiert. Ich weiß, wie man es benutzt, aber wenn ich eins bauen will, ist es etwas anderes ... Ich werde es dokumentieren.Eine Regex zum Extrahieren von SQL Where-Klausel

Ich möchte die WHERE-Klausel in einer SQL-Abfrage extrahieren. Mein Ziel ist es, eine Bedingung hinzuzufügen, wie folgt aus:

SELECT * FROM myTbl WHERE columnA = 'B' AND columnB = 'C' ORDER BY columnX GROUP BY columnZ LIMIT 5 

TO:

SELECT * FROM myTbl WHERE columnC = 'D' AND (columnA = 'B' AND columnB = 'C') ORDER BY columnX GROUP BY columnZ LIMIT 5 

ich einige Ausdruck versucht, aber ich bin so nichtig ...

(where (.*)(?<=order by)) 

Ich wollte alles zwischen "wo" und ("order by" oder "limit" oder "group by") bekommen ...

Wer hat einen Ratschlag für mich? Ich habe eine Suche gemacht und ich finde nichts dergleichen. Ich habe SQL Parser gefunden, aber diese Engines sind zu groß im Vergleich zu der Aufgabe, die ich abschließen möchte.

Vielen Dank.

+1

Ich weiß nicht, wie generisch Sie das brauchen, aber müssen Sie mehr als eine where-Klausel, z. in einer Unterabfrage? – Paddy

+0

Ich habe ein ähnliches Problem und am nächsten komme ich mit diesem Ausdruck: (?:^| \)) (?: [^ \ (\)] +) (?: where \ s +) (. *?) (? : Gruppe von | Order by | $) –

Antwort

2

Da die WHERE Klausel recht komplex sein kann (einschließlich Unterabfragen, die ein ORDER BY in einigen Fällen können zum Beispiel, wenn sie mit FOR XML verwendet wird), so dass Sie mit einem regulären Ausdruck nicht wirklich eine immer zuverlässig funktionierende Lösung in der Lage zu finden.

Eine bessere Lösung wäre, einen richtigen SQL-Parser zu verwenden, der eine AST generiert, und dann können Sie einfach die WHERE-Klausel daraus extrahieren. Für T-SQL können Sie den Parser aus dem Projekt bsn ModuleStore (LGPL-Lizenz) verwenden. Das Ändern der AST ist einfach und Sie können die Anweisung anschließend neu schreiben.

+0

Danke deine Lucero. Ich werde JSQLParser verwenden http://jsqlparser.sourceforge.net/ – LarZuK

+0

Großartig, danke für das Feedback. – Lucero

1

Sie verwenden Lookbehind (? < =), während Sie Lookahead (? =) Assertion benötigen.

Es gibt more darauf.

0

Dies könnte erhalten Sie gehen:

declare 
    sql_stmt varchar2(4000) := q'!SELECT * FROM myTbl WHERE columnA = 'B' AND columnB = 'C' ORDER BY columnX GROUP BY columnZ LIMIT 5!'; 

    where_stmt varchar2(4000) ; 

begin 
    where_stmt := regexp_replace(sql_stmt, '.*(WHERE.*?)ORDER BY.*', '\1'); 

    dbms_output.put_line(where_stmt); 

end; 
/

Die scriplet oben ausgeben wird WHERE columnA = 'B' AND columnB = 'C'.

Verwandte Themen