Регулярное выражение для соответствия синтаксису 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);
}