Oracle序列nextval和currval令人困惑

时间:2018-07-03 07:37:18

标签: oracle plsql

在我的程序中,我写了

INSERT INTO questions(id, value) VALUES(my_seq.NEXTVAL, p_question);

INSERT INTO DEPENDENCIES(parent_question_id, child_question_id)
VALUES (my_seq.CURRVAL, my_seq.NEXTVAL);

比方说序列的最后一个值等于1。在这种情况下,我希望得到以下结果:

 my_seq.NEXTVAL = 2;
 my_seq.CURRVAL = 2;
 my_seq.NEXTVAL = 3;

但是它插入了:

 my_seq.NEXTVAL = 2;
 my_seq.CURRVAL = 3;
 my_seq.NEXTVAL = 3;

我想知道为什么oracle用这种方式检索序列值?

2 个答案:

答案 0 :(得分:14)

如果您有三个不同的语句:

  1. 下一个

  2. 当前时间

  3. 下一个

那么您将是正确的。但是你只有两个

  1. 下一个

  2. currval和nextval

Currval和nextval是单个原子步骤的一部分-currval在nextval之前不会得到处理。

您需要为此使用变量:

DECLARE
  l_parent_question_id     NUMBER ;
  l_child_question_id      NUMBER ;
BEGIN
  l_parent_question_id := my_seq.NEXTVAL ;

  INSERT INTO questions(id, value) VALUES(l_parent_question_id, p_question);

  l_child_question_id := my_seq.NEXTVAL ;

  INSERT INTO DEPENDENCIES(parent_question_id, child_question_id)
  VALUES (l_parent_question_id, l_child_question_id); 

END ;

答案 1 :(得分:3)

只需跟进克里斯蒂安的解释,this is the documented behaviour

  

如果这些位置中的任何一个包含对CURRVALNEXTVAL的引用,则Oracle递增序列,并为CURRVALNEXTVAL返回相同的值。

在这种情况下,“位置”是列表中位于“每个INSERT语句中包含VALUES子句”之前的项目。