java - 如何在给定 Oracle SQL 字符串的情况下提取选定的列?

标签 java sql regex evaluation

好吧,这似乎太难发布在这里,所以请原谅。为此工作了将近一周。

我需要提取给定 Oracle SQL 字符串中的所有选定列。它应该通过以下测试用例:

// 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"

我在 Java 中尝试了以下正则表达式

 ((?<=select\ )(?!distinct\ ).*?(?=,|from))
 ((?<=select\ distinct\ ).*?(?=,|from))
 ((?<=as\ ).*?(?=,|from))
 ((?<=,\ ).*?(?=,|from))(?!.*\ as\ ) // <- Right, I'm guessing here

将它们组合在一起,但我不能简单地通过上面的所有测试用例。 (我正在使用此 tool 来验证我的正则表达式)。

我尝试搜索 SQL 评估器,但找不到任何提取所有列而不针对真实数据库执行它的工具,并且假设所有引用的表和函数都存在。

可以通过测试的 Java ReGex、免费的 SQL Evaluator(不需要真正的数据库),或者任何比这两个更好的东西都是可以接受的答案。假设 SQL 始终采用 Oracle 11g 格式。

最佳答案

鉴于 Oracle SELECT 列表可能变得相当复杂(必须考虑您提到的所有情况,加上子查询、tablename.columnname 构造、带引号的别名等),您可能希望超越正则表达式并实际解析然后 SQL 查询从解析的输出中提取标记。

为此,您有几种不同的选择,其中没有一个那么容易,但可能能够解决您的问题

  • 如果您愿意使用 Perl,您可能可以制作 SQL::Parser做你想做的事。
  • 您可以获得 gsqlparser 的 90 个免费试用版下载如果您想要一个基于 java 的解决方案,如果这是一个一次性项目,这将很有帮助。
  • 有这个 - SQL92 parser ,这是一个免费下载,但许可证未知,而且我不完全确定它是否可以处理任何 Oracle 特定的奇怪问题。
  • 您可以使用 Antlr 生成基于 this guy's work 的具有 java 接口(interface)的 SQL 解析器。 ,它基于 CREATE TABLE 语法,但可以轻松修改以处理 SELECT 语法(或者您可以搜索 antlr sql 语法 并轻松找到预制语法)

关于java - 如何在给定 Oracle SQL 字符串的情况下提取选定的列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14331263/

相关文章:

sql - 为什么要在 sql 函数名前加上前缀?

python - 仅替换模式中的第二次出现

java - Java中无符号右移负数

用于嵌入式系统的 Java?

java - 什么是NullPointerException,我该如何解决?

sql - 如何设置列的默认值?

mysql - 获取满足SQL中最左条件的第一条记录

java - 基于 Cron 的作业,位于数据库中

java - 特殊字符之间多个单词的正则表达式

regex - Jmeter正则表达式排除模式问题