Java PreparedStatement在execute()上抱怨SQL语法

时间:2011-06-14 07:19:13

标签: java mysql syntax jdbc prepared-statement

这让我疯了......我在这里做错了什么?

ArrayList<String> toAdd = new ArrayList<String>();
toAdd.add("password");
try{
    PreparedStatement pStmt = conn.prepareStatement("ALTER TABLE testTable ADD ? varchar(100)");
        for (String s : toAdd) {
            pStmt.setString(1, s);
            pStmt.execute();
        }
} catch (SQLException e) {
    e.printStackTrace();
}

结果......

  

02:59:12,885 ERROR [STDERR] com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:SQL语法中有错误;查看与您的MySQL服务器版本对应的手册,以便在第1行的''password'varchar(100)'附近使用正确的语法

但是...

ArrayList<String> toAdd = new ArrayList<String>();
toAdd.add("password");
try{
    Statement stmt = conn.prepareStatement();
        for (String s : toAdd) {
            stmt.execute("ALTER TABLE testTable ADD "+s+" varchar(100)");
        }
} catch (SQLException e) {
    e.printStackTrace();
}

完美运行......直接将文本直接输入MySQL命令行客户端。

mysql> alter table testTable add stringGoesHere varchar(100);
Query OK, 1 row affected (0.23 sec)
Records: 1  Duplicates: 0  Warnings: 0

我做错了什么?

6 个答案:

答案 0 :(得分:9)

MySQL manual明确指出?(参数标记)仅用于绑定数据值,而不是列名称。

  

参数标记只能使用   应该出现数据值的地方,而不是   对于SQL关键字,标识符等   类推。

所以你必须使用你的第二种方法。

答案 1 :(得分:1)

JDBC中的占位符用于数据,而不是表,列,视图或函数名称。并且有充分的理由。应用程序的数据库模式大部分时间都是静态的,只是很少更改。没有任何好处使它们充满活力。

答案 2 :(得分:1)

准备好的语句需要定义固定的结构,以便对它们进行预编译。这意味着您可以拥有变量,但永远不会有变量表名,列名,函数名等。

答案 3 :(得分:1)

使用预准备语句时,您的参数将被视为字符串文字。因此,您的语句相当于“ALTER TABLE testTable ADD \”“+ s +”\'varchar(100)“。请注意错误消息中字段名称周围的单引号。

我建议在这种情况下构建一个文字语句,而不是试图使用准备好的语句。

答案 4 :(得分:-1)

您不能使用这样的参数提交ALTER TABLE语句。

我想在Java PreparedStatement中执行DDL语句是不允许的。

答案 5 :(得分:-1)

尝试使用以下

pStmt.executeUpdate();

pStmt.close();