java.sql.SQLSyntaxErrorException:ORA-00933:INSERT INTO SELECT未正确结束SQL命令

时间:2017-01-20 15:38:38

标签: java oracle jdbc

我有一个下面的查询,需要通过使用列作为键来选择一行并返回生成的键。

INSERT INTO t_tpms_cc_request
            (process_identifier,
             request_source_id,
             amount,
             etc_account_id,
             retry_count,
             status,
             store_identifier,
             version_no,
             next_process_time,
             composite_transaction_id,
             payment_id,
             processed_time,
             replenishment_id,
             pay_type,
             agency_id,
             response_code,
             file_id,
             request_date,
             auth_file_id,
             auth_date_time,
             merc_file_id,
             merc_date_time,
             cc_num,
             cc_expiration_date,
             merchant_id,
             ext_sys_ref,
             encrypt_cc_number,
             cc_month_cd,
             cc_year_cd,
             orig_txn_ref,
             auth_code,
             avs_code,
             cvv_code)
SELECT CC.process_identifier,
       CC.request_source_id,
       CC.amount,
       CC.etc_account_id,
       CC.retry_count,
       CC.status,
       CC.store_identifier,
       CC.version_no,
       CC.next_process_time,
       CC.composite_transaction_id,
       CC.payment_id,
       CC.processed_time,
       CC.replenishment_id,
       CC.pay_type,
       CC.agency_id,
       CC.response_code,
       CC.file_id,
       CC.request_date,
       CC.auth_file_id,
       CC.auth_date_time,
       CC.merc_file_id,
       CC.merc_date_time,
       CC.cc_num,
       CC.cc_expiration_date,
       CC.merchant_id,
       CC.ext_sys_ref,
       CC.encrypt_cc_number,
       CC.cc_month_cd,
       CC.cc_year_cd,
       CC.orig_txn_ref,
       CC.auth_code,
       CC.avs_code,
       CC.cvv_code
FROM   t_tpms_cc_request CC
WHERE  CC.order_id = ?

而且,我已经在下面编写了一个java代码:

String key[] = {"order_id"}; 

DataSource ds = null;  
Connection con = null;
ResultSet rs = null;
try {
      ds = jdbcTemplate.getDataSource();
      con = ds.getConnection();
      PreparedStatement ps = 
          con.prepareStatement(insertCCRequest.trim(), key);
    ps.setString(1, OrderId);
      int i= ps.executeUpdate();
      rs = ps.getGeneratedKeys();
      if (rs.next()) {
         return rs.getString(1);
      }
} catch (SQLException e) {
    logger.debug("SQL exception in RebillDao.insertCCrequest() 
                                       method..!! ");
    logger.debug("Exception cause: "+e.getMessage());
    e.printStackTrace();
    throw e;
}
finally {
      if(con!=null){
            con.close();
      }          
}
return "";

当我运行时,我得到以下异常:

java.sql.SQLSyntaxErrorException: ORA-00933: SQL command not properly ended

请告诉我解决此问题的方法。

此外,使用 JDk 1.6 ojdbc6-11.2.0.4.jar

1 个答案:

答案 0 :(得分:1)

我怀疑当您使用生成的密钥和预准备语句时,Oracle JDBC驱动程序会将RETURNING INTO子句添加到INSERT语句中,并且JDBC驱动程序太暗,无法实现{ {1}}子句不能与RETURNING INTO语句一起使用。如果我尝试运行INSERT INTO ... SELECT ...语句,我会收到相同的ORA-00933错误。

您可以尝试的是PL / SQL块,我们将“旧”行提取到记录中,然后使用带有INSERT INTO ... SELECT ... RETURNING ...子句的INSERT ... VALUES语句将值插入到'新的'行:

RETURNING_INTO

当我们从中返回值时,我们需要将其准备为CallableStatement而不是PreparedStatement,我们需要将参数2注册为out参数。然后,我们可以使用此out参数,而不是您当前使用的DECLARE l_row t_tpms_cc_request%ROWTYPE; BEGIN SELECT * INTO l_row FROM t_tpms_cc_request WHERE order_id = ?; INSERT INTO t_tpms_cc_request (some_column, some_other_column, ...) VALUES (l_row.some_column, l_row.some_other_column, ...) RETURNING order_id INTO ?; END; 方法,来返回生成的键值。

显然,这种方法是特定于Oracle的,不适用于其他数据库。我不知道有多少问题是数据库可移植性,也不知道是否可以从其他数据库中的getGeneratedKeys()语句返回生成的密钥。