Регулярное выражение для соответствия синтаксису SQL?

Я писал несколько тестов Unit на прошлой неделе для фрагмента кода, который сгенерировал некоторые инструкции SQL.

Я пытался найти регулярное выражение для соответствия синтаксису SELECT, INSERT и UPDATE, чтобы я мог проверить, что мои методы генерируют действительный SQL, и через 3-4 часа поиска и беспорядка с различными редакторами regex я сдался.

Мне удалось получить частичные совпадения, но поскольку раздел в кавычках может содержать любые символы, которые он быстро расширяет, чтобы соответствовать всему статуту.

Любая помощь будет оценена, я не очень хорошо разбираюсь в регулярных выражениях, но я хотел бы узнать больше о них.

Кстати, это С# regex, за которым я после.

Разъяснение

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

Ответы

Ответ 1

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

Ответ 2

SQL является типом-2 грамматикой, он слишком мощный, чтобы описываться регулярными выражениями. Это так же, как если бы вы решили сгенерировать код С#, а затем проверить его без вызова компилятора. Механизм базы данных в целом слишком сложный, чтобы его можно было легко заглушить.

Тем не менее, вы можете попробовать ANTLR SQL grammars.

Ответ 3

Насколько я знаю, это не соответствует регулярному выражению, и вы приближаетесь к темным искусствам BnF и компиляторов.

http://savage.net.au/SQL/

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

Ответ 4

Сверху моей головы: Не могли бы вы передать сгенерированный SQL в базу данных и использовать EXPLAIN на них и уловить любые исключения, которые указывают на плохо сформированный SQL?

Ответ 5

У меня была та же проблема: подход, который будет работать для всех более стандартных операторов sql, будет заключаться в том, чтобы развернуть базу данных Sqlite в памяти и выдать запрос против нее, если вы вернете "таблицу не существует", ошибка, тогда ваш запрос обрабатывался правильно.

Ответ 6

Вы пробовали ленивые селектора. Вместо того, чтобы соответствовать как можно больше, они соответствуют как можно меньше, что, вероятно, вам нужно для цитат.

Ответ 7

Я предполагаю, что вы сделали что-то вроде ". *" вместо этого вместо "[^" ] * ", который не позволит вам съесть всю строку. Он все равно будет давать ложные срабатывания в случаях, когда вы" внутри ваших строк ".

Ответ 8

Чтобы проверить запросы, просто запустите их с помощью SET NOEXEC ON, так как это делает Entreprise Manager при анализе запроса без выполнения он.

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

Ответ 9

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

Ответ 10

Я не думаю, что вам даже нужно иметь созданную схему, чтобы иметь возможность проверять утверждение, потому что система не будет пытаться разрешить имя_объекта и т.д., пока не будет успешно проанализирована инструкция.

С Oracle в качестве примера вы наверняка получите сообщение об ошибке:

select * from non_existant_table;

В этом случае "ORA-00942: таблица или представление не существует".

Однако, если вы выполните:

select * frm non_existant_table;

Затем вы получите синтаксическую ошибку: "ORA-00923: ключевое слово FROM не найдено, где ожидалось".

Должно быть возможно классифицировать ошибки в синтаксическом анализе ошибок, которые указывают на неправильный синтаксис и ошибки, связанные с именем и разрешениями таблиц и т.д.

Добавьте к этому проблему разных РСУБД и даже разных версий, допускающих разные синтаксисы, и я думаю, что вам действительно нужно перейти к движку db для этой задачи.

Ответ 11

ANTLR grammars для синтаксического анализа SQL. Это действительно лучшая идея использовать в базе данных памяти или очень легкую базу данных, такую ​​как sqlite. Мне кажется бесполезным проверить, является ли SQL действительным с точки зрения синтаксического анализа, и гораздо полезнее проверять имена таблиц и столбцов и особенности вашего запроса.

Ответ 12

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

Ответ 13

public bool IsValid(string sql)
{
string pattern = @"SELECT\s.*FROM\s.*WHERE\s.*";
Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase);
return rgx.IsMatch(sql);
}