Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
正在插入后获取插入的ID。。。在Oracle上选择_Oracle_Spring_Jdbc_Insert_Ora 00933 - Fatal编程技术网

正在插入后获取插入的ID。。。在Oracle上选择

正在插入后获取插入的ID。。。在Oracle上选择,oracle,spring,jdbc,insert,ora-00933,Oracle,Spring,Jdbc,Insert,Ora 00933,如果我从Oracle客户端(SQL开发人员)运行此SQL语句,则该SQL语句有效: 如果我通过Spring JDBC发布它,而不使用: 但是,我需要使用一个钥匙夹来获取新插入行的ID。如果我将上述代码更改为使用钥匙夹,如下所示: final KeyHolder keyHolder = new GeneratedKeyHolder(); final PreparedStatementCreator psc = new PreparedStatementCreator() { @Overr

如果我从Oracle客户端(SQL开发人员)运行此SQL语句,则该SQL语句有效:

如果我通过Spring JDBC发布它,而不使用:

但是,我需要使用一个钥匙夹来获取新插入行的ID。如果我将上述代码更改为使用钥匙夹,如下所示:

final KeyHolder keyHolder = new GeneratedKeyHolder();
final PreparedStatementCreator psc = new PreparedStatementCreator() {

    @Override
    public PreparedStatement createPreparedStatement(Connection con)
        throws SQLException
    {
        return con.prepareStatement(
            "insert into Person (Name) select 'Bob' from dual",
            new String[] {"PersonID"});
    }
};
jdbcOperations.update(psc, keyHolder);
。。。然后我得到这个错误:

Exception in thread "main" org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: ORA-00933: SQL command not properly ended
    at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:94)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:80)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:602)
    at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:842)
    at au.com.bisinfo.codecombo.logic.ImportServiceImpl.insertLoginRedirectRule(ImportServiceImpl.java:107)
    at au.com.bisinfo.codecombo.logic.ImportServiceImpl.runImport(ImportServiceImpl.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at $Proxy8.runImport(Unknown Source)
    at au.com.bisinfo.codecombo.ui.Main.main(Main.java:39)
Caused by: java.sql.SQLSyntaxErrorException: ORA-00933: SQL command not properly ended
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:439)
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:395)
    at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:802)
    at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:436)
    at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:186)
    at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:521)
    at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:205)
    at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:1008)
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1307)
    at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:3449)
    at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:3530)
    at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1350)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:105)
    at org.springframework.jdbc.core.JdbcTemplate$3.doInPreparedStatement(JdbcTemplate.java:844)
    at org.springframework.jdbc.core.JdbcTemplate$3.doInPreparedStatement(JdbcTemplate.java:1)
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:586)
    ... 15 more
FWIW,如果我做一个插入,一切都很好。。。值而不是插入。。。选择(尽管这对我没有帮助,因为我需要选择一些东西):

我正在使用:

  • SpringJDBC3.0.3.0版本
  • JDBC驱动程序:ojdbc6.jar版本11.2.0.1.0
  • RDBMS:Oracle9i 9.2.0.5.0版-生产
  • commons dbcp 1.4
注意:我的应用程序需要使用标准SQL才能保持数据库中立,这就排除了任何特定于Oracle的SQL(在现实生活中,我不会从“dual”中进行选择)

谢谢您的帮助。

界面清晰

创建一个默认PreparedStatement对象,该对象具有检索自动生成密钥的功能

所以你使用了错误的方法。试一试

return con.prepareStatement(
        "insert into Person (Name) select 'Bob' from dual",
        Statement.RETURN_GENERATED_KEYS);
相反

怎么样

INSERT INTO blah b (blah1, blah2, blah3)
VALUES (?, ?, ?) RETURNING b.id INTO ?";

Oracle JDBC驱动程序不支持此功能

我怀疑使用带有INSERT SELECT语句的密钥保持器不受支持,因为SELECT理论上可以选择多行,如果选择了,则无法将多个密钥返回到单个密钥保持器中。对于您试图完成的任务,简单地使用select语句和insert语句可能更容易。

该方法是可以返回生成键的三种方法之一,另外两种是prepareStatement(String,int[])和prepareStatement(String,String[])。我使用的是后者,这是Oracle的正确输入法。不过,我还是会试试你的建议,让你知道它是怎么回事。@Andrew Swan你是对的。非常感谢。但是让我知道输出我不能使用插入。。。值,因为我需要选择内容。另外,我不想使用返回。。因为这是甲骨文特有的。这就是我的猜测;你有这方面的参考资料吗?
final KeyHolder keyHolder = new GeneratedKeyHolder();
final PreparedStatementCreator psc = new PreparedStatementCreator() {

    @Override
    public PreparedStatement createPreparedStatement(Connection con)
        throws SQLException
    {
        return con.prepareStatement(
            "insert into Person (Name) values ('Bob')",
            new String[] {"PersonID"});
    }
};
jdbcOperations.update(psc, keyHolder);
return con.prepareStatement(
        "insert into Person (Name) select 'Bob' from dual",
        Statement.RETURN_GENERATED_KEYS);
INSERT INTO blah b (blah1, blah2, blah3)
VALUES (?, ?, ?) RETURNING b.id INTO ?";