2013-05-21 1 views
2

Есть ли регулярное выражение, которое извлекает SQL-запросы из строки? Я NOT заинтересован в проверке любого синтаксиса SQL, а также только на извлечение набора команд SQL. Это позволяет гибко анализировать данный файл/строку SQL.Регулярное выражение для извлечения SQL-запроса

Приведен следующий пример SQL файл/строка:

SELECT 
    * 
FROM 
    test_table 
WHERE 
    test_row = 'Testing ; semicolon'; 

SELECT * FROM another_test_table; 

INSERT INTO 
    table_name 
VALUES 
    (value1,'value which contains semicolon ;;;;',value3,...); 

Некоторые псевдокод примером может быть: ^(UPDATE|SELECT|INSERT INTO)(.*)(;)$. В будущем я хочу расширить это с помощью всех (возможных) команд.

  • Посмотрите на стартовом матче с либо: (ДОПОЛНЕНО | ВЫБРАТЬ | INSERT | INTO)
  • Ноль или более any character (включая Пробелы и переводы строк)
  • Остановка на ;, который разграничивает запрос SQL.

Всякий раз, когда это будет возможно с помощью регулярных выражений следующий код Java может извлечь все SQL команды:

final String regex = "LOOKING_FOR_THIS_ONE"; 
final Pattern p = Pattern.compile(regex, Pattern.MULTILINE); 
final Matcher matcher = p.matcher(content); 

while (matcher.find()) { 
    // matcher.group() now contains the full SQL command 
} 

Спасибо заранее!

+1

Не затрудняйте свою жизнь, поместите запросы в файл свойств (с любым ключом), загрузите его и выполните итерацию над valueSet. –

+0

Это не возможное решение, так как мне нужно работать, я получаю, я не могу требовать формат ввода. Вход представляет собой текстовый файл, содержащий команды SQL, которые мне нужно извлечь/проанализировать. – Velth

+3

Любой шанс для тех, кто создал эту строку, чтобы включить ...? Использование простого текста для структурированной информации и принуждение разработчика к работе с ним кажется преднамеренной жестокостью. –

ответ

0

(?m)^(UPDATE|SELECT|INSERT INTO).*;$ должно работать. Это расширит шаблон, чтобы он соответствовал символам новой строки. Он должен иметь возможность прокручивать и находить все ваши SQL.

Посмотрев пример, который вы указали, он будет соответствовать вашим командам до ;. Вы можете увидеть пример, используемый для тестирования here.

0

Если вы имеете дело с языком, создайте лексер, который символизирует вашу строку. Используйте JFlex, который является генератором лексического анализатора. Он генерирует класс Java, который разбивает строку на токены на основе грамматики, заданной в специальном файле. Возьмите соответствующие правила грамматики от this file.

Анализ - это отдельный процесс, чем токенизация (или лексический анализ). Возможно, вы захотите использовать генератор парсера после лексического анализа, если лексического анализа недостаточно.

1

Вы можете сопоставить его «правильно», если точка с запятой является последним символом без пробела в этой строке.

final String regex = ^(SELECT|UPDATE|INSERT)[\s\S]+?\;\s*?$ 

final Pattern p = Pattern.compile(regex, Pattern.MULTILINE); 
final Matcher matcher = p.matcher(content); 
+0

Это также работает с несколькими строковыми SQL-запросами. Благодаря! –

2

Начнет с того, что это не очень хорошим способом сделать это, и настоятельно призывает вас, чтобы найти другой способ сделать это, предпочтительно мечением это правильно, где сделаны заявления, так что вы не В конце концов, в этой ситуации.

При этом SQL требует, чтобы он начинался с одного из следующих; DELETE, SELECT, WITH, UPDATE или INSERT INTO. Он также требует, чтобы вход заканчивался ;.

Мы можем использовать это, чтобы захватить все последовательности, соответствующие SQL со следующим:

final String regex = "^(INSERT INTO|UPDATE|SELECT|WITH|DELETE)(?:[^;']|(?:'[^']+'))+;\\s*$"; 
final Pattern p = Pattern.compile(regex, Pattern.MULTILINE | Pattern.DOTALL); 

Группа 1 в настоящее время занимает рабочее слово, в случае, если вы хотите, чтобы фильтровать действительный SQL на UPDATE или SELECT.

Смотрите регулярное выражение в действии, а также пещеру-на здесь:

https://regex101.com/r/dt9XTK/2

0

SQL достаточно сложна, что вам понадобится контекст, чтобы найти все заявления, что означает, что вы не можете сделать это с регулярным выражением.

Например:

SELECT Model FROM Product 
WHERE ManufacturerID IN (SELECT ManufacturerID FROM Manufacturer 
WHERE Manufacturer = 'Dell') 

(пример взят из http://www.sql-tutorial.com/sql-nested-queries-sql-tutorial/). Вложенные запросы могут вставляться несколько раз, начинать с разных значений и т. Д. Если вы можете написать регулярное выражение для интересующего вас подмножества, оно будет нечитаемым.

ANTLR имеет доступное SQL 2003 grammar (я не пробовал).

 Смежные вопросы

  • Нет связанных вопросов^_^