0

OK、これはここに投稿するには難しすぎるように思えるかもしれませんので、ご容赦ください。これにほぼ1週間取り組んできました。

特定の 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

それらを OR で結合しましたが、上記のすべてのテスト ケースを単純にパスすることはできません。(このツールを使用して正規表現を検証しています)。

SQL エバリュエーターを検索してみましたが、実際のデータベースに対して実行せずにすべての列を抽出し、参照されるすべてのテーブルと関数が存在すると想定するものは見つかりません。

Java ReGex、テストに合格できる無料の SQL エバリュエーター (実際のデータベースは必要ありません)、またはこれら 2 つよりも優れたものが受け入れられる答えです。SQL は常に Oracle 11g 形式であることが前提です。

4

1 に答える 1

1

Oracle SELECT リストがかなり複雑になる可能性があることを考えると (言及したすべてのケースに加えて、サブクエリ、tablename.columnname 構造、引用されたエイリアスなどを考慮する必要があります)、おそらく正規表現を超えて、実際に SQL クエリを解析することをお勧めします。解析された出力からトークンを引き出します。

そのために、いくつかの異なるオプションがあり、どれもそれほど簡単ではありませんが、問題を解決できる可能性があります

  • Perl を使用したい場合は、おそらくSQL::Parserでやりたいことを実行できます。
  • Java ベースのソリューションが必要な場合は 、 gsqlparserの 90 日間無料試用版をダウンロードできます。これは、これが 1 回限りのプロジェクトである場合に役立ちます。
  • これがあります-SQL92パーサーは無料でダウンロードできますが、ライセンスは不明です.Oracle固有の奇妙さを処理できるかどうかは完全にはわかりません.
  • Antlr を使用して、この男の作業に基づいた Java インターフェイスを備えた SQL パーサーを生成できます。これは、CREATE TABLE 構文に基づいていますが、SELECT 構文を処理するように容易に適応させることができます (または、事前に作成されたantlr sql grammarものを非常に簡単に検索して見つけることができます)。
于 2013-01-15T05:26:52.097 に答える