2012-02-12 82 views
8

此准备好的声明对我来说似乎是有效的SQL。Mysql下降表作为PreparedStatement不适用于我

PreparedStatement dropTable = cnx.prepareStatement(
    "DROP TABLE IF EXISTS ?"); 
dropTable.setString(1, "features"); 
dropTable.execute(); 

但是当我运行它,我得到的错误:

Exception in thread "main" 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 ''features'' at line 1 at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.lang.reflect.Constructor.newInstance(Constructor.java:532) at com.mysql.jdbc.Util.handleNewInstance(Util.java:406) at com.mysql.jdbc.Util.getInstance(Util.java:381) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1031) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3558) at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3490) at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1959) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2109) at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2648) at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2077) at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1356) at doriangray.db.TestSetup.main(TestSetup.java:62)

有谁看到这里的问题?我很难过。

+4

我没有进入Java,但是我知道的所有预编译语句库都不支持动态表名。 – 2012-02-12 20:32:40

回答

7

MySQL不支持用变量表名预处理语句,所以你必须这样做的老式方法,通过生成SQL:

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

在这种情况下,您不妨使用常规语句,因为您没有通过使用预准备语句获得任何内容。

1

我觉得你的代码准备这样一句话:当你想

DROP TABLE IF EXISTS 'features' 

DROP TABLE IF EXISTS features 
1

的PreparedStatement用于制作数据库汇总查询(使执行计划)一次,所以在执行具有不同参数的查询发生得更快。

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

0

您不能使用预准备语句删除具有动态表名称的表。但是,如果直到运行时才知道表名,并且它们可能有空格,那么您需要将它们放在back-ticks中:

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