2016-08-27 9 views
0

javaのSQLクエリでAntlrパーサを使用してwhere句をフェッチしようとしています。私は得る方法を知らなかった。誰かが答えることができます....事前に感謝します。SQLを取得する方法Javaを使用しているANTLRのノードexpr

SELECT student.name, 
     student.student_id, 
     event.date, 
     event.event_id, 
     event.type 
FROM student, event 
LEFT JOIN score 
    ON student.student_id = score.student_id AND 
     event.event_id = score.event_id 
WHERE score.score IS NULL 
ORDER BY student.student_id, 
     event.event_id; 

Answer.score IS NULLを回答にします。

私はこのように試してみました...

System.out.println("hello join"); 
    SQLiteLexer lexer = new SQLiteLexer(new ANTLRInputStream(subQuery)); 
    SQLiteParser parser = new SQLiteParser(new CommonTokenStream(lexer)); 
    Map<String, ArrayList<String>> joinQueryMap = new HashMap<String, ArrayList<String>>(); 
    final ArrayList<String> functionNames = new ArrayList<String>(); 
    final ArrayList<String> columnNames = new ArrayList<String>(); 
    final ArrayList<String> tableNames = new ArrayList<String>(); 
    final ArrayList<String> joinTypeList = new ArrayList<String>(); 
    final ArrayList<String> joinConsList = new ArrayList<String>(); 

    ParseTree tree = parser.select_stmt(); 
    final TableFamily tableFamily=new TableFamily(); 

    ParseTreeWalker.DEFAULT.walk(new SQLiteBaseListener() {   
     @Override 
     public void enterExpr(SQLiteParser.ExprContext ctx) { 
      if (ctx.function_name() != null) { 
       functionNames.add(ctx.function_name().getText()); 
      } 
      if (ctx.column_name() != null) { 
       columnNames.add(ctx.column_name().getText());      
      } 
     }      
     public void enterSelect_stmt(SQLiteParser.Select_stmtContext ctx){ 
      //System.out.println(ctx.select_or_values(0).join_clause().table_or_subquery(0).getText());    
      if(ctx.select_or_values()!=null){ 
       int len=ctx.select_or_values().get(0).join_clause().table_or_subquery().size(); 
       //System.out.println("len is "+len); 
       for(int i=0;i<len;i++){      
        boolean aliasFlag=false; 
        tableNames.add(ctx.select_or_values().get(0).join_clause().table_or_subquery().get(i).table_name().getText()); 
        tableFamily.setTableName(ctx.select_or_values().get(0).join_clause().table_or_subquery().get(i).table_name().getText()); 
        //System.out.println("Table-> "+ctx.select_or_values().get(0).join_clause().table_or_subquery().get(i).table_name().getText()); 

        if(ctx.select_or_values().get(0).join_clause().table_or_subquery().get(i).table_alias()!=null){ 
         //System.out.println("Table Alias-> "+ctx.select_or_values().get(0).join_clause().table_or_subquery().get(i).table_alias().getText()); 
         tableFamily.setTableAlias(ctx.select_or_values().get(0).join_clause().table_or_subquery().get(i).table_name().getText()); 
         aliasFlag=true; 
        } 
        //System.out.println("flag-> "+aliasFlag); 
        for(int j=0;j<ctx.select_or_values().get(0).result_column().size();j++){ 
         String columns=ctx.select_or_values().get(0).result_column().get(j).getText(); 
         if(columns.contains("(")&&columns.contains("")){ 
          //System.out.println(columns); 
          columns=columns.substring(columns.indexOf("(")+1, columns.indexOf(")")); 
         } 
         //System.out.println("columns-> "+columns); 
         String columnArr[]=columns.split("\\."); 
         //System.out.println(columnArr[0]+" %% "+columnArr[1]); 
         //System.out.println("check-> "+ctx.select_or_values().get(0).join_clause().table_or_subquery().get(i).table_alias().getText().equals(columnArr[0])); 
         if(aliasFlag && ctx.select_or_values().get(0).join_clause().table_or_subquery().get(i).table_alias().getText().equals(columnArr[0])){ 
          System.out.println("col1 "+columnArr[1]); 
         } 
         else{ 
          System.out.println("col "+columns); 
         } 
        }      
        System.out.println(); 
       } 
       for(int k=0;k<ctx.select_or_values(0).join_clause().join_operator().size();k++){ 
        System.out.println("Join Type-> "+ctx.select_or_values(0).join_clause().join_operator().get(k).getText()); 
        joinTypeList.add(ctx.select_or_values(0).join_clause().join_operator().get(k).getText()); 
       } 
       for(int l=0;l<ctx.select_or_values(0).join_clause().join_constraint().size();l++){ 
        System.out.println("Join Constraint-> "+ctx.select_or_values(0).join_clause().join_constraint().get(l).expr().getText()); 
        joinConsList.add(ctx.select_or_values(0).join_clause().join_constraint().get(l).expr().getText()); 
       } 
       System.out.print("\n"); 
      }    
     }      
    }, tree); 
    joinQueryMap.put("\nFunction Names", functionNames); 
    joinQueryMap.put("\nColumn Names", columnNames); 
    joinQueryMap.put("\nTable Names", tableNames); 
    joinQueryMap.put("\nJoin Type", joinTypeList); 
    joinQueryMap.put("\nJoin Constraint", joinConsList); 

    /*System.out.println("sFunction Names "+functionNames); 
    System.out.println("sColumn Names "+columnNames); 
    System.out.println("Table Names "+tableNames);*/ 
    System.out.println("tab "+tableFamily.getTableName()); 
    System.out.println("tab1 "+tableFamily.getTableAlias()); 
    return joinQueryMap; 
+0

'FROM student、event' ...この廃止予定の(構文は本当に古い)構文であることに注意してください。おそらく、これらの2つのテーブル間のクロス結合、または少なくともあなたが参加しているタイプやっていることは、あなたが意図しているよりも制限が少ないかもしれません。 –

+0

私は単純なものから同じように必要です... select id、id = 10のテーブルからの名前;これからantlrparserを使ってwhere節が必要です。 –

答えて

0

あなたは私たちにあなたが使用する文法を示していないと、あなたの問題が何であるかを教えていなかった(間違った結果を得るか、ないの結果、コンパイルされません、何でも)。だから私はここで少し推測しなければならない。

最初に、パース結果を取得するためにリスナーにenterXXX関数を使用しないでください。入力時には、設定されていますが、これまでのところ、そのサブツリーでは何も解析されません。したがって、通常は代わりにexitXXX関数を使用します。次に、where句だけに興味がある場合は、文法を見てください。 whereのルールが考えられます(where_clauseとしましょう)。

public void exitWhere_clause(SQLiteParser.Where_clauseContext ctx) { 
    // Handle here the expression you are after. 
} 

これで、出口リスナー関数を作成することができます。手動で式サブツリーをダイビングするのは面倒な作業なので、式を扱うだけの別のリスナーを作成することをお勧めします。これをwhere句関数のsublistenerとしてインスタンス化して、where式だけを実行します(構文解析ツリー全体でこれを使用しないでください。または、状況がさまざまな場所で発生する可能性があるため、常にコンテキストをチェックする必要があります)。代わりに、ローカル式リスナーを使用すると、where句で式部分のみを解析することができます。

+0

私はantlrの新人ですので、where節、groupbyなどのための独自のリスナーを書く方法を教えてください。 –

+0

where節のリスナーは必要ありません。 )。上記のメイン・リスナーに別のオーバーライドを追加するだけです(正確な構文は文法によって異なります)。そのオーバーライドされた関数では、別のリスナーを作成し、ローカルウォークを開始することができます( 'ParseTreeWalker.DEFAULT.walk(新しいSQLiteBaseListener(){...'のみ 'where'コンテキストを使います。あなたが望むものに近いものによって)、それは正確にあなたに必要な情報を与える必要があります。 –

関連する問題