Как извлечь выбранные столбцы с учетом строки 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 и найти готовый довольно легко)
Другие вопросы по тегам