这个问题已经在这里有一个答案:
- 如何获得JDBC插入ID? 11个回答
有没有在表中插入一行,并获得新生成的ID的任何方式,只在一个声明? 我想使用JDBC,并将由序列来生成的ID或将是一个自动增量字段。
谢谢你的帮助。
约翰·杨
这个问题已经在这里有一个答案:
有没有在表中插入一行,并获得新生成的ID的任何方式,只在一个声明? 我想使用JDBC,并将由序列来生成的ID或将是一个自动增量字段。
谢谢你的帮助。
约翰·杨
使用的getGeneratedKeys():
resultSet = pstmt.getGeneratedKeys();
if (resultSet != null && resultSet.next()) {
lastId = resultSet.getInt(1);
}
您可以使用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
其实,我觉得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
我不能发表评论,否则我会加入到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。
关心,罗布
自动生成的ID的价值是不知道执行INSERT后,直到因为其他语句可以同时执行和RDBMS到达决定如何安排哪一个先行。
你在INSERT语句的表达调用任何功能本来就是插入新行前进行评估,因此无法知道是什么产生的ID值。
我能想到的是接近你问两个选项:
写运行AFTER INSERT触发器,所以你可以访问生成的ID键值。
写一个程序来包装插入,这样你就可以在程序执行其他代码和查询最后生成的ID。
不过,我怀疑你实际上问的是你是否可以查询由当前会话最后生成的ID值,即使其他会话也插入行,并生成自己的ID值。 你可以放心, 每一个提供了一个自动递增设施RDBMS提供了一种方法来查询这个值 ,它会告诉你在你当前的会话范围生成的最后一个ID。 这不影响其他会议一样插入。
通过序列生成的ID可以通过获得
insert into table values (sequence.NextVal, otherval)
select sequence.CurrVal
在同一事务跑了作为获得一致的看法。
我想你会有所帮助:
我有一个自动增量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错误从插入返回值时,
我不能发表评论,否则我会刚刚加入到DFA的岗位,但下面是与直接使用JDBC此功能的示例。
http://www.ibm.com/developerworks/java/library/j-jdbcnew/
但是,如果你正在使用的东西,如春天,他们会掩盖很多对你的血淋淋的细节。 如果能为您服务,刚刚好春第11章,这是JDBC的细节。 使用它为我节省了很多麻烦。