【问题标题】:Mysql Drop Table as PreparedStatement not working for meMysql Drop Table as PreparedStatement 不适合我
【发布时间】:2012-03-04 09:00:07
【问题描述】:

这个准备好的语句对我来说似乎是有效的 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) 在 com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1356) 在 doriangray.db.TestSetup.main(TestSetup.java:62)

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

【问题讨论】:

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

标签: java mysql jdbc prepared-statement


【解决方案1】:

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

DROP TABLE IF EXISTS 'features'

随心所欲:

DROP TABLE IF EXISTS features

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      MySQL 不支持带有可变表名的预处理语句,因此您必须通过生成 SQL 来执行此操作:

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

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

      【讨论】:

        【解决方案4】:

        您不能使用准备好的语句来删除具有动态表名的表。但是,如果您直到运行时才知道表名,并且它们可能包含空格,那么您需要将它们括在反引号中:

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

        【讨论】:

          猜你喜欢
          • 2013-07-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-27
          • 1970-01-01
          • 2020-06-30
          • 2018-07-24
          • 2012-05-06
          相关资源
          最近更新 更多