Java Mysql作为PreparedStatement删除表对我不起作用

Java Mysql作为PreparedStatement删除表对我不起作用,java,mysql,jdbc,prepared-statement,Java,Mysql,Jdbc,Prepared Statement,这个准备好的语句对我来说似乎是有效的SQL PreparedStatement dropTable = cnx.prepareStatement( "DROP TABLE IF EXISTS ?"); dropTable.setString(1, "features"); dropTable.execute(); 但当我运行此命令时,我得到了错误: 线程“main”中出现异常 com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorExcepti

这个准备好的语句对我来说似乎是有效的SQL

PreparedStatement dropTable = cnx.prepareStatement(
    "DROP TABLE IF EXISTS ?");
dropTable.setString(1, "features");
dropTable.execute();
但当我运行此命令时,我得到了错误:

线程“main”中出现异常 com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:您有一个 SQL语法错误;检查与您的产品相对应的手册 MySQL服务器版本,以便在 第1行在 sun.reflect.NativeConstructorAccessorImpl.newInstance0(本机方法) 在 sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) 在 sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 位于java.lang.reflect.Constructor.newInstance(Constructor.java:532) 位于com.mysql.jdbc.Util.handleNewInstance(Util.java:406) com.mysql.jdbc.Util.getInstance(Util.java:381)位于 com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1031)位于 com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)位于 com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3558)位于 com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3490)位于 com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1959)位于 com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2109)位于 com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2648)位于 com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2077) 在 execute(PreparedStatement.java:1356) 位于doriangray.db.TestSetup.main(TestSetup.java:62)


有人看到这个问题了吗?我被难住了。

我认为您的代码准备了以下语句:

DROP TABLE IF EXISTS 'features'
尽管你想要:

DROP TABLE IF EXISTS features

PreparedStatements用于使数据库编译查询(制定执行计划)一次,因此使用不同参数执行同一查询的速度更快


简而言之,在PreparedStatement中,数据库对象不能有通配符。包括表名、列名、不同的where子句和……

MySQL不支持具有可变表名的预处理语句,因此您必须以老式的方式生成SQL:

PreparedStatement dropTable = cnx.prepareStatement(
String.format("DROP TABLE IF EXISTS %s", "features"));
dropTable.execute();

在这种情况下,您最好使用常规语句,因为使用prepared语句不会获得任何好处。

您不能使用prepared语句删除具有动态表名的表。但是,如果直到运行时才知道表名,并且表名中可能有空格,则需要将它们括在后面的刻度中:

for (String tableName : tableNames) {
    statement.executeUpdate("DROP TABLE IF EXISTS `" + tableName + "`");
}

我不喜欢Java,但我知道的所有准备好的语句库都不支持动态表名。