与Statement.RETURN_GENERATED_KEYS一起使用时出现PreparedStatement问题

时间:2018-02-12 07:14:33

标签: oracle jdbc prepared-statement

当我尝试将PreparedStatement与Statement.RETURN_GENERATED_KEYS一起使用时,我不知道为什么PreparedStatement对象需要额外的参数。我已经用Google搜索了所有可能的字符串,但没有得到任何回复。

以下是我用于插入记录的代码。

StringBuilder headerSql = new StringBuilder();
headerSql.append("insert into TABLE_XXX(subscriber_id,company_id,stg_inv_id,inv_loc_id,count_date,count_status,count_type,creation_user,creation_date,update_user,update_date) \n");
headerSql.append("(select ?,?,XXXX_PK.NEXTVAL,?,sysdate,0,0,?,sysdate,?,sysdate from dual \n");
headerSql.append("where not exists(select 1 from TABLE_XXX where subscriber_id=? and company_id=? and inv_loc_id=? and count_status=0 and count_type=0)) \n"); 
String stgInvId=null; 
PreparedStatement ps = null;
ResultSet rs = null;
try {           
    ps = con.prepareStatement(headerSql.toString(), Statement.RETURN_GENERATED_KEYS);
    ps.setString(1,Integer.toString(IDObj.getSubscriberID()));
    ps.setString(2,Integer.toString(IDObj.getCompanyID()));
    ps.setString(3,locId);
    ps.setString(4,IDObj.getUserLogin());
    ps.setString(5,IDObj.getUserLogin());
    ps.setString(6,Integer.toString(IDObj.getSubscriberID()));
    ps.setString(7,Integer.toString(IDObj.getCompanyID()));
    ps.setString(8,locId);
    ps.executeUpdate();
    rs = ps.getGeneratedKeys();
    rs.next();
    stgInvId=rs.getString("stg_inv_id");
} catch (Exception e) {                 
    System.out.println(headerSql.toString());
    e.printStackTrace();            
}

下面是绑定的参数列表:

bound parameters

正如您在上面所看到的,我现在不是从添加最后一个参数的位置以及我需要传递给我的值。请指导我们。

下面是Stacktrace:

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

    at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:111)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:330)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:287)
    at oracle.jdbc.driver.T4C8Oall.receive(T4C8Oall.java:742)
    at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:212)
    at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:951)
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1159)
    at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3284)
    at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3367)
    at com.birchstreet.synergy.countmanagement.dao.CountManagementDAOImpl.inserStgHeader(CountManagementDAOImpl.java:325)
    at com.birchstreet.synergy.countmanagement.dao.CountManagementDAOImpl.inserStgRecord(CountManagementDAOImpl.java:280)
    at com.birchstreet.webservices.synergy.WSCountManagement.setLocationsInStartInventory(WSCountManagement.java:138)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory$1.invoke(ResourceMethodInvocationHandlerFactory.java:81)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:143)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:160)
    at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:158)
    at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:97)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347)
    at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102)
    at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:303)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271)
    at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
    at org.glassfish.jersey.internal.Errors.process(Errors.java:267)
    at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317)
    at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:286)
    at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1072)
    at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:399)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:381)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:344)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:221)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:624)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

1 个答案:

答案 0 :(得分:0)

oracle DB RETURN_GENERATED_KEYS以这种方式工作。

1)RETURN_GENERATED_KEYS标志

PreparedStatement ps = con.prepareStatement("INSERT INTO XXX(  A, B) VALUES ( xxx_s.nextval, 'aaa')",Statement.RETURN_GENERATED_KEYS);      
    ps.executeUpdate();        
    ResultSet      rs = ps.getGeneratedKeys();
    while(rs.next()) {
        System.out.println(rs.getString(1));
    }

Oracle不知道哪个列是自动生成的,并且它正在返回rowidreturning rowid into :?附加到插入

2)列列表。

PreparedStatement ps = con.prepareStatement("INSERT INTO XXX(  A, B) VALUES ( xxx_s.nextval, 'aaa')",new String[]{"A"});        
        ps.executeUpdate();        
        ResultSet      rs = ps.getGeneratedKeys();
        while(rs.next()) {
            System.out.println(rs.getString(1));
        }
        con.close();

在这种情况下,我们明确指定自动生成的列。 returning a into :?附加到插入

在这两种情况下,要访问生成的列,您必须使用位置访问权限。不支持按列名访问。

但是你正在尝试insert as select。法规转换为

insert into xxxy  select * from xxxy returning rowid into :var ; 

oracle db不支持此语句。异常ORA-00933: SQL command not properly ended is raised