繁体   English   中英

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

[英]Java PreparedStatement complaining about SQL syntax on execute()

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

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: You have an error in your SQL syntax; 检查与您的 MySQL 服务器版本相对应的手册,了解在第 1 行的“密码”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

我究竟做错了什么?

MySQL 手册清楚地说明了这一点? (参数标记)仅用于绑定数据值,不适用于列名。

参数标记只能用于应出现数据值的位置,不能用于 SQL 关键字、标识符等。

因此,您将不得不使用第二种方法。

JDBC 中的占位符用于数据,而不用于表、列、视图或 function 名称。 并且有充分的理由。 应用程序的 DB 模式大部分时间是 static,很少更改。 使它们动态化没有任何好处。

准备好的语句需要定义一个固定的结构,以便它们可以被预编译。 这意味着你可以有变量,但不能有变量表名、列名、function 名称等。

使用准备好的语句时,您的参数与字符串文字类似。 因此,您的语句等效于“ALTER TABLE testTable ADD \'"+s+"\' varchar(100)”。 请注意错误消息中字段名称周围的单引号。

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

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

我猜Java PreparedStatement中不允许执行DDL语句。

尝试使用以下

pStmt.executeUpdate();

pStmt.close();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM