java.sql.SQLSyntaxErrorException:ORA-00933:sql命令未正确结束,无法插入到SELECT中

java.sql.SQLSyntaxErrorException:ORA-00933:sql命令未正确结束,无法插入到SELECT中,java,oracle,jdbc,Java,Oracle,Jdbc,我有一个下面的查询,它需要使用列作为键来选择一行,并返回生成的键 INSERT INTO t_tpms_cc_request (process_identifier, request_source_id, amount, etc_account_id, retry_count, status, store_identi

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

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
请告诉我解决这个问题的方法


另外,使用JDK1.6ojdbc6-11.2.0.4.jar

我怀疑,当您将生成的键与准备好的语句一起使用时,Oracle JDBC驱动程序会将
RETURNING INTO
子句添加到
INSERT
语句中,JDBC驱动程序太模糊,无法意识到
返回到
子句不能与
插入到一起使用。。。选择…
语句。如果我尝试运行
插入到…中,我会收到相同的ORA-00933错误。。。选择。。。正在返回…
语句

您可以尝试使用PL/SQL块,将“old”行提取到记录中,然后使用
INSERT。。。VALUES
语句,带有一个
RETURNING_INTO
子句,用于将值插入“new”行:

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;
当我们从中返回值时,我们需要将其准备为CallableStatement而不是PreparedStatement,并且需要将参数2注册为out参数。然后,我们可以使用这个out参数,而不是您目前使用的
getGeneratedKeys()
方法来返回生成的键值


显然,这种方法是特定于Oracle的,不适用于其他数据库。我不知道数据库的可移植性对您有多大影响,也不知道您是否可以将
插入生成的密钥返回到。。。在其他数据库中选择…
语句。

我怀疑当您将生成的键与准备好的语句一起使用时,Oracle JDBC驱动程序会将
返回到
子句添加到
插入
语句中,JDBC驱动程序太模糊,无法意识到
返回到
子句不能与
插入到一起使用。。。选择…
语句。如果我尝试运行
插入到…中,我会收到相同的ORA-00933错误。。。选择。。。正在返回…
语句

您可以尝试使用PL/SQL块,将“old”行提取到记录中,然后使用
INSERT。。。VALUES
语句,带有一个
RETURNING_INTO
子句,用于将值插入“new”行:

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;
当我们从中返回值时,我们需要将其准备为CallableStatement而不是PreparedStatement,并且需要将参数2注册为out参数。然后,我们可以使用这个out参数,而不是您目前使用的
getGeneratedKeys()
方法来返回生成的键值


显然,这种方法是特定于Oracle的,不适用于其他数据库。我不知道数据库的可移植性对您有多大影响,也不知道您是否可以将
插入生成的密钥返回到。。。在其他数据库中选择…
语句。

请正确编辑代码。SQL末尾是否需要分号?是否尝试使用大写列名<代码>字符串键[]={“订单ID”}请正确编辑代码。SQL结尾是否需要分号?是否尝试使用大写列名<代码>字符串键[]={“订单ID”}多糟糕的人啊。最后,我将insert拆分为select,分成两个查询,首先获取数据,然后使用一个简单的
insert into。。。值
。显然,我支付了oracle->java->oracle等的往返费用,但我发现更容易查看PL/SQL,尤其是在没有性能问题之前。真遗憾,4年后,我们的司机仍然有这个问题。真是个无赖。最后,我将insert拆分为select,分成两个查询,首先获取数据,然后使用一个简单的
insert into。。。值
。显然,我支付了oracle->java->oracle等的往返费用,但我发现更容易查看PL/SQL,尤其是在没有性能问题之前。真遗憾,4年后我们的司机仍然有这个问题。