情况如下:
我有一个表(GUI_FILTER)和一个序列(GUI_FILTER_SEQ) 我使用springjdbctemplate插入数据,也可以使用核心jdbc。 在插入查询中,我正在检索sequence.nextval,并使用keyholder将其提取回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();
如果我删除序列生成部分选择MAPS_AMPS.AMPS_GUI_FILTER_SEQ.NEXTVAL
为常数大约30左右,它可以正常工作。
有没有办法将序列值作为insert命令获取,同时使用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;
}
错误
答案 0 :(得分: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)