Регулярное выражение для извлечения SQL, где предложение - PullRequest
2 голосов
/ 17 января 2011

Во-первых, признаюсь, я не экспериментировал с регулярными выражениями.Я знаю, как его использовать, но когда я хочу его создать, это что-то другое ... Я собираюсь задокументировать меня.

Я хочу извлечь предложение WHERE в запросе SQL.Моя цель - добавить условие, например:

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

Я попробовал какое-то выражение, но я так пуст ...

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

Я хотел получить все между «где» и («упорядочить по» или «ограничить» или «сгруппировать по») ...

У кого-нибудь есть совет для меня?Я провел поиск и ничего подобного не нахожу.Я нашел SQL Parser, но эти механизмы слишком велики по сравнению с задачей, которую я хочу выполнить.

Спасибо.

Ответы [ 3 ]

2 голосов
/ 17 января 2011

Поскольку предложение WHERE может быть довольно сложным (включая подзапросы, которые в некоторых случаях могут включать ORDER BY, например, при использовании с FOR XML), поэтому вы не сможете найти действительно надежно работающий решение с регулярным выражением.

Лучшим решением было бы использовать правильный синтаксический анализатор SQL, который генерирует AST , и тогда вы можете просто извлечь из него предложение WHERE. Для T-SQL вы можете использовать анализатор из проекта bsn ModuleStore (лицензия LGPL). Изменить AST легко, и вы можете перепрограммировать оператор после этого.

1 голос
/ 17 января 2011

Вы используете lookbehind (? <=), В то время как вам нужно утверждение lookahead (? =). </p>

На этом больше .

0 голосов
/ 17 января 2011

Это может помочь вам:

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;
/

При написании scriplet выше WHERE columnA = 'B' AND columnB = 'C'.

...