Регулярное выражение для извлечения SQL, где предложение
Во-первых, я признаюсь, что я не экспериментировал с регулярными выражениями. Я знаю, как его использовать, но когда я хочу создать его, это что-то другое... Я собираюсь задокументировать меня.
Я хочу извлечь предложение WHERE в запросе SQL. Моя цель - добавить условие, например:
SELECT * FROM myTbl WHERE columnA = 'B' AND columnB = 'C' ORDER BY columnX GROUP BY columnZ LIMIT 5
ДО:
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 ответа
Так как WHERE
предложение может быть довольно сложным (включая подзапросы, которые могут включать в себя ORDER BY
в некоторых случаях, например, при использовании с FOR XML
), так что вы не сможете найти действительно надежно работающее решение с регулярным выражением.
Лучшим решением было бы использовать правильный синтаксический анализатор SQL, который генерирует AST, а затем вы можете просто извлечь WHERE
пункт из этого. Для T-SQL вы можете использовать парсер из проекта bsn ModuleStore (лицензия LGPL). Изменить AST легко, и вы можете перепрограммировать оператор впоследствии.
Вы используете lookbehind (?<=), Тогда как вам нужно утверждение lookahead (?=).
Там больше об этом.
Это может заставить вас идти:
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;
/
Скрипт выше выведет WHERE columnA = 'B' AND columnB = 'C'
,