【问题标题】:Fetch primary key generated by sequence using jdbctemplate / jdbc使用 jdbctemplate / jdbc 获取序列生成的主键
【发布时间】:2016-09-24 03:19:07
【问题描述】:

情况如下:

我有一个表(GUI_FILTER)和一个序列(GUI_FILTER_SEQ) 我正在使用 springjdbctemplate 插入数据,也可以使用核心 jdbc。 在插入查询中,我正在检索 sequence.nextval 并使用密钥持有者将其取回给 java,如下所示。 我尝试了几种方法,例如使用

returnRowCount = namedJdbctmplt.update(sql.toString(), namedParameters, keyHolder, keyColumnNames);

returnRowCount = jdbctemplate.update(psc, keyHolder);

两个都失败了,

org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: ORA-00936: missing expression



StringBuilder sql = new StringBuilder();
        sql.append(" Insert Into MAPS_AMPS.AMPS_GUI_FILTER ");
        sql.append(" (FILTER_PRESET_ID,USER_ID,FILTER_PAGE_TXT,FILTER_DISPLY_NM,FILTER_DATA_TXT,ROW_CREATE_TMS,LAST_UPDT_TMS ) ");
        sql.append(" values(Select MAPS_AMPS.AMPS_GUI_FILTER_SEQ.NEXTVAL,?,?,?,?,CURRENT_TIMESTAMP ,null from dual) ");
        final String sqlQuery = sql.toString();

如果我删除序列生成部分 Select MAPS_AMPS.AMPS_GUI_FILTER_SEQ.NEXTVAL 到 30 左右这样的常量,它工作正常。

有什么方法可以获取序列值作为插入命令,同时使用 jdbc 获取主键?

完整代码如下。

@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, rollbackFor = DataAccessException.class)
public Long addFilterPreset(final String userId, final String filterPageCd,
        final String filterPresetDisplayName,
        final String serializedTaskBrowserSearchObj) {

    logger.debug("Start of FilterPresetDaoImpl - addFilterPreset() method");

    if(!countSavedFilterPresets(userId,filterPageCd))
        return null;

    //StringBuilder sql = new StringBuilder();
    Map<String, Object> parameterMap = new HashMap<String, Object>();

    //sql.append(" Insert Into MAPS_AMPS.AMPS_GUI_FILTER ");
    //sql.append(" (FILTER_PRESET_ID,USER_ID,FILTER_PAGE_TXT,FILTER_DISPLY_NM,FILTER_DATA_TXT,ROW_CREATE_TMS,LAST_UPDT_TMS ) ");
    //sql.append( "Values( Select MAPS_AMPS.AMPS_GUI_FILTER_SEQ.NEXTVAL,:userId,:filterPageCd,:filterPresetDisplayName,:filterPresetData,CURRENT_TIMESTAMP ,null)" );

    /*parameterMap.put("userId", userId);
    parameterMap.put("filterPageCd", filterPageCd);
    parameterMap.put("filterPresetDisplayName", filterPresetDisplayName);
    parameterMap.put("filterPresetData", serializedTaskBrowserSearchObj);
    */
    StringBuilder sql = new StringBuilder();
    sql.append(" Insert Into MAPS_AMPS.AMPS_GUI_FILTER ");
    sql.append(" (FILTER_PRESET_ID,USER_ID,FILTER_PAGE_TXT,FILTER_DISPLY_NM,FILTER_DATA_TXT,ROW_CREATE_TMS,LAST_UPDT_TMS ) ");
    sql.append(" values(Select MAPS_AMPS.AMPS_GUI_FILTER_SEQ.NEXTVAL,?,?,?,?,CURRENT_TIMESTAMP ,null from dual) ");
    final String sqlQuery = sql.toString();

    logger.info("SQL Add Filter Preset Query : {}", sqlQuery);
    int returnRowCount = 0;
    KeyHolder keyHolder = new GeneratedKeyHolder();
    final String[] keyColumnNames = {"FILTER_PRESET_ID"};
    SqlParameterSource namedParameters = new MapSqlParameterSource(parameterMap);

    PreparedStatementCreator psc = new PreparedStatementCreator()   {
        @Override
        public PreparedStatement createPreparedStatement(Connection connection)
                throws SQLException     {
            PreparedStatement ps = connection.prepareStatement(sqlQuery, keyColumnNames);
            ps.setString(1, userId);
            ps.setString(2, filterPageCd);
            ps.setString(3, filterPresetDisplayName);
            ps.setString(4, serializedTaskBrowserSearchObj);
            return ps;
        }
    };

    try{
        long startValue = System.currentTimeMillis();
        //returnRowCount = namedJdbctmplt.update(sql.toString(), namedParameters, keyHolder, keyColumnNames);
        returnRowCount = jdbctemplate.update(psc, keyHolder);
        long endValue = System.currentTimeMillis();
        logger.info("Filter Preset added in {} seconds", (endValue - startValue)/1000);
    }catch(Exception e){
        logger.info("Exception while adding filter preset - " + "userId : "+userId+" filterPageCd : "+filterPageCd +" filterPresetData : "+serializedTaskBrowserSearchObj);
    }finally{
        logger.debug("End of FilterPresetDaoImpl - addFilterPreset() method");
    }
    if (returnRowCount > 0)
        return keyHolder.getKey().longValue();
    return null;
}

错误

【问题讨论】:

    标签: java sql jdbc oracle11g


    【解决方案1】:

    插入查询结果时不需要 VALUES 关键字。

    StringBuilder sql = new StringBuilder();
            sql.append(" Insert Into MAPS_AMPS.AMPS_GUI_FILTER ");
            sql.append(" (FILTER_PRESET_ID,USER_ID,FILTER_PAGE_TXT,FILTER_DISPLY_NM,FILTER_DATA_TXT,ROW_CREATE_TMS,LAST_UPDT_TMS ) ");
            sql.append(" (Select MAPS_AMPS.AMPS_GUI_FILTER_SEQ.NEXTVAL,?,?,?,?,CURRENT_TIMESTAMP ,null from dual) ");
            final String sqlQuery = sql.toString();
    

    要获得插入的值,请尝试使用 RETURNING 子句:本文Oracle's RETURNING INTO usage in Java (JDBC, Prepared Statement) 中讨论了一些细节

    但是,只有在使用 VALUES 关键字时才能对 INSERT 使用 RETURNING 子句,因此不能同时使用两者。正如这里所讨论的:PLSQL Insert into with subquery and returning clause (Oracle)

    【讨论】:

      猜你喜欢
      • 2017-04-07
      • 1970-01-01
      • 2014-04-08
      • 1970-01-01
      • 1970-01-01
      • 2020-09-27
      • 2016-04-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多