Mysql Drop Table作为PreparedStatement不适合我

时间:2012-02-12 20:29:24

标签: 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.MySQLSyntaxErrorException:你有一个   SQL语法错误;查看与您的手册相对应的手册   MySQL服务器版本,用于在''features'附近使用正确的语法   第1行   sun.reflect.NativeConstructorAccessorImpl.newInstance0(本机方法)     在   sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)     在   sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)     at java.lang.reflect.Constructor.newInstance(Constructor.java:532)     在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 at   com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)at at   com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3558)at at   com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3490)at at   com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1959)at at   com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2109)at at   com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2648)at at   com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2077)     在   com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1356)     在doriangray.db.TestSetup.main(TestSetup.java:62)

有人在这看到问题吗?我很难过。

4 个答案:

答案 0 :(得分:8)

MySQL不支持带有变量表名的预处理语句,所以你必须通过生成SQL以旧方式执行此操作:

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

在这种情况下,你也可以使用常规语句,因为你没有通过使用预准备语句获得任何东西。

答案 1 :(得分:1)

我认为你的代码准备了这个陈述:

DROP TABLE IF EXISTS 'features'

当你想要的时候:

DROP TABLE IF EXISTS features

答案 2 :(得分:1)

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

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

答案 3 :(得分:0)

您不能使用预准备语句删除具有动态表名的表。但是,如果您在运行时之前不知道表名,并且它们中可能有空格,那么您需要将它们包含在后面的标记中:

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