【问题标题】:H2 database does not accept a table name as named parameterH2 数据库不接受表名作为命名参数
【发布时间】:2014-09-24 21:14:58
【问题描述】:

我在尝试对内存中的 H2(版本 1.4.181)表运行以下查询时遇到问题:

Object result = hibernateSession
                  .createSQLQuery("show columns from :myTable")
                  .setString("myTable", "some_table")
                  .list();

此查询导致以下异常:

Caused by: org.h2.jdbc.JdbcSQLException: Syntax error in SQL statement "SHOW COLUMNS FROM ?[*] "; expected "identifier"; SQL statement: show columns from ? [42001-181]
...
...
...

我做了一些调试,发现在解析查询的过程中,字符“?”测试它是否是一个有效的标识符并且它失败了,导致异常的上升(类 org.h2.command.Parser,第 3027 行):

//currentToken is "?" at this point
if (currentTokenType != IDENTIFIER) {
        throw DbException.getSyntaxError(sqlCommand, parseIndex,
                "identifier");
    }

我认为这是一个错误。你怎么看?

【问题讨论】:

  • SQL 绑定变量不能像那样引用元数据。您需要生成像show columns from some_table 这样的动态 SQL 并执行它。

标签: java sql h2


【解决方案1】:

不,这很正常。 Hibernate 不可能对其进行 PreparedStatement。

标准 JDBC 以独立于数据库供应商的方式有多种查询模式等的可能性。

DatabaseMetaData dbMeta = connection.getMetaData();

那么getColumns可以用来接收一个ResultSet的杂项信息。

【讨论】:

    【解决方案2】:
    • 您可以尝试创建所需的查询,而不是将表名设置为命名参数,这不起作用。

       String sqlQuery = "show columns from " + tableName;
       Class<?> entity = Class.forName(entityName);
      
       session.createSQLQuery(sqlQuery);
      
    • 获取元数据信息,然后可以从中检索所需的详细信息。

      字符串[] 属性 = sessionFactory.getClassMetadata(entityClass).getPropertyNames();

      还有其他几种获取元信息的方法,可以参考ClassMetaData

    [我没有检查Criteria API,如果发现任何相关内容会更新,您可以尝试一下]

    【讨论】:

      猜你喜欢
      • 2018-02-08
      • 2014-08-10
      • 2017-11-25
      相关资源
      最近更新 更多