Как извлечь выбранные столбцы с учетом строки Oracle SQL?
Хорошо, это может показаться слишком сложным для размещения здесь, поэтому я прошу прощения. Работал над этим почти неделю.
Мне нужно извлечь все выбранные столбцы в данной Oracle SQL String. Он должен пройти следующие тестовые случаи:
// single column test
select col1 from dual
// ^ should match "col1"
// multiple column test
select col1,col2 from dual
// ^ should match "col1", "col2"
// multiple space test
select col1 , col2 from dual
// ^ should match "col1", "col2"
// "distinct" tests
select distinct col1 from dual
// ^ should match "col1"
select distinct col1, col2 from dual
// ^ should match "col1", "col2"
// "distinct" with whitespaces tests
select distinct col1 from dual
// ^ should match "col1"
select distinct col1 , col2 from dual
// ^ should match "col1", "col2"
// "as" tests
select col1 from dual
// ^ should match "col1"
select colA as col1 from dual
// ^ should match "col1"
select colA as col1, col2, col3 from dual
// ^ should match "col1", "col2", "col3"
select col1, colB as col2, col3 from dual
// ^ should match "col1", "col2", "col3"
select col1, col2, colC as col3 from dual
// ^ should match "col1", "col2", "col3"
// "as" tests with whitespaces tests
select colA as col1, colB as col2, colC as col3 from dual
// ^ should match "col1", "col2", "col3"
// "distinct" with "as" tests
select distinct colA as col1 from dual
// ^ should match "col1"
select distinct colA as col1, colB as col2, col3 from dual
// ^ should match "col1", "col2", "col3"
select distinct colA as col1, col2, colC as col3 from dual
// ^ should match "col1", "col2", "col3"
// function test
select funct('1','2') as col1 from dual
// ^ should match "col1"
select col1, funct('1','2') as col2 from dual
// ^ should match "col1", "col2"
select col1, colB as col2, funct('1','2') as col3 from dual
// ^ should match "col1", "col2", "col3"
Я попробовал следующий RegEx в Java
((?<=select\ )(?!distinct\ ).*?(?=,|from))
((?<=select\ distinct\ ).*?(?=,|from))
((?<=as\ ).*?(?=,|from))
((?<=,\ ).*?(?=,|from))(?!.*\ as\ ) // <- Right, I'm guessing here
ИЛИ их вместе, но я не могу просто пройти все тестовые примеры выше. (Я использую этот инструмент для проверки моего регулярного выражения).
Я попытался найти оценщик SQL, но не могу найти ни одного, который извлекает все столбцы, не выполняя его для реальной базы данных и который предполагает, что все ссылочные таблицы и функции существуют.
Java ReGex, бесплатный SQL Evaluator (который не нуждается в реальной базе данных), который может пройти тесты, или что-нибудь лучше, чем эти два, являются приемлемыми ответами. Предполагается, что SQL всегда в формате Oracle 11g.
1 ответ
Учитывая, что списки Oracle SELECT могут быть довольно сложными (с учетом всех упомянутых вами случаев, а также подзапросов, конструкций tablename.columnname, псевдонимов в кавычках и т. Д.), Вы, вероятно, захотите выйти за рамки регулярных выражений и фактически проанализировать SQL-запрос. вытащить токены из проанализированного вывода.
Для этого у вас есть пара различных вариантов, ни один из которых не так прост, но может решить вашу проблему.
- Если вы хотите использовать Perl, вы можете заставить SQL::Parser делать то, что вы хотите.
- Вы можете получить 90 бесплатных пробных версий gsqlparser, если вам нужно решение на основе Java, которое будет полезно, если это одноразовый проект.
- Существует такой синтаксический анализатор SQL92, который можно бесплатно загрузить, но с неизвестной лицензией, и я не совсем уверен, сможет ли он справиться с какой-либо специфической для Oracle странностью.
- вы можете использовать Antlr для генерации парсера SQL с интерфейсом java на основе работы этого парня, которая основана на синтаксисе CREATE TABLE, но может быть легко адаптирована для обработки синтаксиса SELECT (или вы можете искать
antlr sql grammar
и найти готовый довольно легко)