获得在同一语句插入的ID [复制](Obtain id of an insert in the sa

2019-06-23 10:26发布

这个问题已经在这里有一个答案:

  • 如何获得JDBC插入ID? 11个回答

有没有在表中插入一行,并获得新生成的ID的任何方式,只在一个声明? 我想使用JDBC,并将由序列来生成的ID或将是一个自动增量字段。

谢谢你的帮助。

约翰·杨

Answer 1:

使用的getGeneratedKeys():

resultSet = pstmt.getGeneratedKeys(); 

if (resultSet != null && resultSet.next()) { 
    lastId = resultSet.getInt(1); 
}


Answer 2:

您可以使用RETURNING子句让你更新或插入任何列的值。 它与触发(即:你得到触发器执行后实际插入值)。 考虑:

SQL> CREATE TABLE a (ID NUMBER PRIMARY KEY);

Table created
SQL> CREATE SEQUENCE a_seq;

Sequence created
SQL> VARIABLE x NUMBER;
SQL> BEGIN
  2     INSERT INTO a VALUES (a_seq.nextval) RETURNING ID INTO :x;
  3  END;
  4  /

PL/SQL procedure successfully completed
x
---------
1

SQL> /

PL/SQL procedure successfully completed
x
---------
2


Answer 3:

其实,我觉得NEXTVAL之后CURRVAL没有工作。 下面是一些代码,模拟与两个线程,一个是首先进行NEXTVAL,那么CURRVAL这种行为,而第二个线程做了NEXTVAL之间。

public void checkSequencePerSession() throws Exception {
     final Object semaphore = new Object();
     Runnable thread1 = new Runnable() {
        public void run() {
           try {
              Connection con = getConnection();
              Statement s = con.createStatement();
              ResultSet r = s.executeQuery("SELECT SEQ_INV_BATCH_DWNLD.nextval AS val FROM DUAL ");
              r.next();
              System.out.println("Session1 nextval is: " + r.getLong("val"));
              synchronized(semaphore){
                 semaphore.notify();
              }
              synchronized(semaphore){
                 semaphore.wait();
              }
              r = s.executeQuery("SELECT SEQ_INV_BATCH_DWNLD.currval AS val FROM DUAL ");
              r.next();
              System.out.println("Session1 currval is: " + r.getLong("val"));
              con.commit();
           } catch (Exception e) {
              e.printStackTrace();
           }
        }
     };
     Runnable thread2 = new Runnable(){
        public void run(){
           try{
              synchronized(semaphore){
                 semaphore.wait();
              }
              Connection con = getConnection();
              Statement s = con.createStatement();
              ResultSet r = s.executeQuery("SELECT SEQ_INV_BATCH_DWNLD.nextval AS val FROM DUAL ");
              r.next();
              System.out.println("Session2 nextval is: " + r.getLong("val"));
              con.commit();
              synchronized(semaphore){
                 semaphore.notify();
              }
           }catch(Exception e){
              e.printStackTrace();
           }
        }
     };
     Thread t1 = new Thread(thread1);
     Thread t2 = new Thread(thread2);
     t1.start();
     t2.start();
     t1.join();
     t2.join();
}

其结果如下:SESSION1 NEXTVAL是:47会话2 NEXTVAL是:48 SESSION1 CURRVAL是:47



Answer 4:

我不能发表评论,否则我会加入到Vinko Vrsalovic的帖子:

The id generated by a sequence can be obtained via 

insert into table values (sequence.NextVal, otherval)
select sequence.CurrVal

ran in the same transaction as to get a consistent view.

从中得到一个NEXTVAL之后更新德序列是一个自治事务。 否则,另一个会话将得到序列相同的值。 所以,如果anothers sesssion已经从序列中的插入和选择之间的选择变得CURRVAL不会得到插入的ID。

关心,罗布



Answer 5:

自动生成的ID的价值是不知道执行INSERT后,直到因为其他语句可以同时执行和RDBMS到达决定如何安排哪一个先行。

你在INSERT语句的表达调用任何功能本来就是插入新行前进行评估,因此无法知道是什么产生的ID值。

我能想到的是接近你问两个选项:

  • 写运行AFTER INSERT触发器,所以你可以访问生成的ID键值。

  • 写一个程序来包装插入,这样你就可以在程序执行其他代码和查询最后生成的ID。

不过,我怀疑你实际上问的是你是否可以查询由当前会话最后生成的ID值,即使其他会话也插入行,并生成自己的ID值。 你可以放心, 每一个提供了一个自动递增设施RDBMS提供了一种方法来查询这个值 ,它会告诉你在你当前的会话范围生成的最后一个ID。 这不影响其他会议一样插入。



Answer 6:

通过序列生成的ID可以通过获得

insert into table values (sequence.NextVal, otherval)
select sequence.CurrVal

在同一事务跑了作为获得一致的看法。



Answer 7:

我想你会有所帮助:

我有一个自动增量ID的表。 从我不时要插入行此表,但希望能够知道新插入行的PK是什么。

String query = "BEGIN INSERT INTO movement (doc_number) VALUES ('abc') RETURNING id INTO ?; END;";
OracleCallableStatement cs = (OracleCallableStatement) conn.prepareCall(query);
cs.registerOutParameter(1, OracleTypes.NUMBER );
cs.execute();
System.out.println(cs.getInt(1));

来源: 螺纹:甲骨文/ JDBC错误从插入返回值时,



Answer 8:

我不能发表评论,否则我会刚刚加入到DFA的岗位,但下面是与直接使用JDBC此功能的示例。

http://www.ibm.com/developerworks/java/library/j-jdbcnew/

但是,如果你正在使用的东西,如春天,他们会掩盖很多对你的血淋淋的细节。 如果能为您服务,刚刚好春第11章,这是JDBC的细节。 使用它为我节省了很多麻烦。



文章来源: Obtain id of an insert in the same statement [duplicate]