2011-02-27 7 views
0

言語、国、インストールの3種類のフィールドを持つテーブルを作成しました。それぞれの分野で最大の出現価値を印刷するためのクエリを書くとき、私は奇妙な問題を抱えています。誰でも理由を言うことができます。これは私のコードです。JavaのPrepareStatementに関する問題

PreparedStatement ps1= null; 
ps1 = conn.prepareStatement("desc Configuration"); 

ResultSet rs1=ps1.executeQuery(); 
while(rs1.next()) { 

    System.out.print(rs1.getString(1)+":"); 

    PreparedStatement ps2= null; 

    ps2 = conn.prepareStatement("select ? from Configuration c1 "+ 
           " group by language "+ 
           " having count(*) >= all " + 
           "  (select count(*) from Configuration c2 "+ 
           "   group by language)"); 

    ps2.setString(1,rs1.getString(1)); 

    ResultSet rs2=ps2.executeQuery(); 

    while(rs2.next()) 
     System.out.print(rs2.getString(1)); 

    System.out.println(); 
} 

私はここで取得しています出力は言語である:言語しかし、私は期待していどのような出力が 言語である:そのような英語。もし私が '?'準備文の中で言葉で話しています。でも、もし私が同じことを言えば?私はps2.setStringのために与えてきたものを得ています。

なぜこれが起こっているのですか?どんな解決策ですか?

答えて

1

'?' ps2のマークはリテラル文字列として認識されます。列名ではありません。

2

PreparedStatementを使用して列名を設定することはできません。列の値のみを設定できます。

代わりに、このアプローチを使用して、あなたは例えば、自分が連結を使用してSQLを構築する必要があります:プリペアドステートメントで

String sql = "select "+ rs1.getString(1) + " from Configuration c1 group by language having count(*) >= all(select count(*)from Configuration c2 group by language)"; 
5

?は、テキスト置換のプレースホルダではない、それは、したがって、その値のパラメータですクエリ構文の任意の部分ではなく、常にデータとして解釈されます。

この場合、実行される実際のクエリはselect 'language' from ...に相当します。

あなたはデータ以外のクエリの一部を置換する必要がある場合は、連結を使用する必要があります(SQLインジェクションに注意!):

ps2 = conn.prepareStatement("select " 
    + rs1.getString(1) 
    + " from Configuration c1 group by language having count(*) >= all(select count(*)from Configuration c2 group by language)"); 
+0

@allは....ありがとう – Allwyn

関連する問題