0

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

我需要提取给定 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 中尝试了以下 RegEx

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

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

我尝试搜索 SQL 求值器,但找不到任何可以提取所有列而不对真实数据库执行它并且假定所有引用的表和函数都存在的方法。

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

4

1 回答 1

1

鉴于 Oracle SELECT 列表可能会变得非常复杂(必须考虑您提到的所有情况,加上子查询、tablename.columnname 结构、引用的别名等),您可能想要超越正则表达式并实际解析 SQL 查询从解析的输出中拉出标记。

为此,您有几个不同的选择,但都不是那么容易,但也许能够解决您的问题

  • 如果你愿意使用 Perl,你可以让SQL::Parser做你想做的事。
  • 如果您想要一个基于 java 的解决方案,您可以获得gsqlparser的 90 次免费试用下载,如果这是一个一次性项目,这将很有帮助。
  • 有这个 - SQL92 parser,它是免费下载的,但许可证未知,我不完全确定它是否可以处理任何特定于 Oracle 的怪事。
  • 你可以使用 Antlr 生成一个基于这个人的工作的带有 java 接口的 SQL 解析器,它基于 CREATE TABLE 语法,但可以很容易地适应处理 SELECT 语法(或者你可以antlr sql grammar很容易地搜索并找到一个预制的)
于 2013-01-15T05:26:52.097 回答