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

发布于 2024-10-20 09:30:59 字数 3467 浏览 2 评论 0原文

我使用 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();

并存储我使用GenerateKeyHolder的查询。但在运行时我得到一个异常:

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

I am using HSQLDB as my database. i want to get a primary key of latest inserted row. for that i have return a query in my java class as below:

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();

and to store the query i have used GeneratedKeyHolder. but while runing this i get an exception:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

驱逐舰岛风号 2024-10-27 09:30:59

问题出在这一行(为了清楚起见,将其换行):

最终字符串查询 =“INSERT INTO polling_log (start_date,status,action) VALUES(CURRENT_TIMESTAMP,?,?); CALL IDENTITY();”;

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

最终字符串查询 = "INSERT INTO polling_log (start_date,status,action) VALUES(CURRENT_TIMESTAMP,?,?); CALL \"IDENTITY\"();";

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

The problem is with this line (wrapped for clarity):

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

The issue is that IDENTITY is a reserved word in SQL; it's got a meaning pre-defined already and so can't be used like that in a CALL statement. (I don't know what it is actually used for; the full definition of SQL is huge and has a very large number of reserved words.) The immediate work around would be to enclose the problem word in double quotes (which would need to be backslash-quoted because of being in a Java string):

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

However, if you're just calling that to get the inserted row, STOP! Just let Spring do the work for you, assuming you have JDBC 3.0 or later (i.e., Java 5 or later).

只为一人 2024-10-27 09:30:59

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

As far as I know you cannot put more than one statements into one string to be executed. Execute two separate operations instead of this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文