如何解决org.springframework.jdbc.BadSqlGrammarException:PreparedStatementCallback;

时间:2011-03-04 05:59:15

标签: sql spring prepared-statement hsqldb

我使用HSQLDB作为我的数据库。我想获得最新插入行的主键。因为我已经在我的java类中返回一个查询,如下所示:

final String query = "INSERT INTO polling_log (start_date,status,action) VALUES(CURRENT_TIMESTAMP,?,?); CALL IDENTITY();";
    GeneratedKeyHolder generatedKeyHolder = new GeneratedKeyHolder();
    int update = adapterJdbcTemplate.update(new PreparedStatementCreator() {
        @Override
        public PreparedStatement createPreparedStatement(
                Connection connection) throws SQLException {

            PreparedStatement preparedStatement = connection
                    .prepareStatement(query);
            preparedStatement.setInt(1, pollingLogVO.getStatus());
            preparedStatement.setString(2, pollingLogVO.getAction());
            System.out.println(preparedStatement.getGeneratedKeys().getFetchSize());
            return preparedStatement;
        }
    }, generatedKeyHolder);

    System.out.println("###################### "+ update);

    Number logId = generatedKeyHolder.getKey();
    pollingLogId = logId.intValue();

并存储我使用过GeneratedKeyHolder的查询。但是在运行这个时我得到了一个例外:

org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar []; nested exception is java.sql.SQLException: unexpected token: IDENTITY
    at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:98)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:602)
    at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:817)
    at com.platysgroup.lmex.adapter.moodle.dao.LogDao.insertPollingLog(LogDao.java:36)
    at com.platysgroup.lmex.adapter.MoodlePostingTask.insertPollingLog(MoodlePostingTask.java:134)
    at com.platysgroup.lmex.adapter.MoodlePostingTask.run(MoodlePostingTask.java:55)
    at java.util.TimerThread.mainLoop(Timer.java:512)
    at java.util.TimerThread.run(Timer.java:462)
Caused by: java.sql.SQLException: unexpected token: IDENTITY
    at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
    at org.hsqldb.jdbc.JDBCPreparedStatement.<init>(Unknown Source)
    at org.hsqldb.jdbc.JDBCConnection.prepareStatement(Unknown Source)
    at org.apache.commons.dbcp.DelegatingConnection.prepareStatement(DelegatingConnection.java:248)
    at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.prepareStatement(PoolingDataSource.java:302)
    at com.platysgroup.lmex.adapter.moodle.dao.LogDao$1.createPreparedStatement(LogDao.java:41)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:580)
    ... 6 more
Caused by: org.hsqldb.HsqlException: unexpected token: IDENTITY
    at org.hsqldb.error.Error.parseError(Unknown Source)
    at org.hsqldb.ParserBase.unexpectedToken(Unknown Source)
    at org.hsqldb.ParserCommand.compileStatement(Unknown Source)
    at org.hsqldb.Session.compileStatement(Unknown Source)
    at org.hsqldb.StatementManager.compile(Unknown Source)
    at org.hsqldb.Session.execute(Unknown Source)
    ... 12 more

3 个答案:

答案 0 :(得分:0)

据我所知,你不能将多个语句放入一个要执行的字符串中。执行两个单独的操作而不是此操作。

答案 1 :(得分:0)

答案 2 :(得分:0)

问题在于这条线(为清晰起见而包裹):

  

final String query = "INSERT INTO polling_log (start_date,status,action) VALUES(CURRENT_TIMESTAMP,?,?); CALL IDENTITY();";

问题是IDENTITY是SQL中的保留字;它已经具有预先定义的含义,因此不能像CALL语句中那样使用。 (我不知道实际使用的是什么; SQL的完整定义很庞大,并且有很多保留字。)最直接的解决方法是将问题单词用双引号括起来(这需要由于存在于Java字符串中而被反斜杠引用:

  

final String query = "INSERT INTO polling_log (start_date,status,action) VALUES(CURRENT_TIMESTAMP,?,?); CALL \"IDENTITY\"();";

但是,如果您只是调用它来获取插入的行, STOP! 只要让Spring为您工作,假设您有JDBC 3.0或更高版本(即Java 5或更高版本)。