Java PreparedStatement在execute()上抱怨SQL语法
这让我疯了……我在这里做错了什么?
ArrayList toAdd = new ArrayList(); 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 toAdd = new ArrayList(); 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中的占位符用于数据,而不是表,列,视图或函数名称。 并且有充分的理由。 应用程序的数据库模式大部分时间都是静态的,只是很少更改。 没有任何好处使他们充满活力。
准备好的语句需要定义一个固定的结构,以便可以对它们进行预编译。 这意味着你可以拥有变量值 ,但永远不会有变量表名,列名,函数名等。
使用预准备语句时,您的参数将被视为字符串文字。 因此,您的语句相当于“ALTER TABLE testTable ADD \’”+ s +“\’varchar(100)”。 请注意错误消息中字段名称周围的单引号。
我建议在这种情况下构建一个文字语句,而不是试图使用准备好的语句。
您不能使用这样的参数提交ALTER TABLE语句。
我想在Java PreparedStatement中执行DDL语句是不允许的。
尝试使用以下内容
pStmt.executeUpdate();
pStmt.close();