Java中的PreparedStatement问题

时间:2011-02-27 15:07:25

标签: java jdbc

我创建了包含3个字段语言,国家/地区,安装类型的表格。当我写一个查询来打印每个字段中的最大出现值时,我遇到了一个奇怪的问题。任何人都可以说出原因。这是我的代码。

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提供的东西。

为什么会这样。任何解决方案?

3 个答案:

答案 0 :(得分: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 )");  

答案 1 :(得分: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)";

答案 2 :(得分:1)

'?' ps2中的标记被识别为文字字符串。不是列名。