简体   繁体   English

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

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

This is driving me nuts... What am I doing wrong here?这让我发疯......我在这里做错了什么?

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();
}

Results in...结果是...

02:59:12,885 ERROR [STDERR] com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; 02:59:12,885 ERROR [STDERR] com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''password' varchar(100)' at line 1检查与您的 MySQL 服务器版本相对应的手册,了解在第 1 行的“密码”varchar(100) 附近使用的正确语法

but...但...

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();
}

works perfectly... So does directly entering the text directly into the MySQL command line client.完美运行...直接将文本直接输入 MySQL 命令行客户端也是如此。

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

What am I doing wrong?我究竟做错了什么?

The MySQL manual clearly says that ? MySQL 手册清楚地说明了这一点? (parameter markers) are for binding data values only, not for column names. (参数标记)仅用于绑定数据值,不适用于列名。

Parameter markers can be used only where data values should appear, not for SQL keywords, identifiers, and so forth.参数标记只能用于应出现数据值的位置,不能用于 SQL 关键字、标识符等。

So you will have to use your second approach.因此,您将不得不使用第二种方法。

Placeholders in JDBC are for data, not for table, column, view or function names. JDBC 中的占位符用于数据,而不用于表、列、视图或 function 名称。 And for good reason.并且有充分的理由。 The DB schema of an application is static most of the time and only changes rarely.应用程序的 DB 模式大部分时间是 static,很少更改。 There are no benefits making them dynamic.使它们动态化没有任何好处。

Prepared statements need to define a fixed structure so they can be precompiled.准备好的语句需要定义一个固定的结构,以便它们可以被预编译。 That means you can have variable values , but never variable table names, column names, function names etc.这意味着你可以有变量,但不能有变量表名、列名、function 名称等。

When using a prepared statement, your parameter is treated similarily to a string literal.使用准备好的语句时,您的参数与字符串文字类似。 As a result, your statement is equivalent to "ALTER TABLE testTable ADD \'"+s+"\' varchar(100)".因此,您的语句等效于“ALTER TABLE testTable ADD \'"+s+"\' varchar(100)”。 Notice the single quotations around the field name in the error message.请注意错误消息中字段名称周围的单引号。

I would suggest building a literal statement in this case, and not attempting to used a prepared statement.我建议在这种情况下构建一个文字语句,而不是尝试使用准备好的语句。

You cannot submit an ALTER TABLE statement using parameters like this.您不能使用这样的参数提交 ALTER TABLE 语句。

I guess it is not permissible to execute DDL statements in Java PreparedStatement.我猜Java PreparedStatement中不允许执行DDL语句。

Try using the following尝试使用以下

pStmt.executeUpdate(); pStmt.executeUpdate();

pStmt.close(); pStmt.close();

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

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