Oracle序列nextval和currval混淆

Oracle序列nextval和currval混淆,oracle,plsql,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

在我的程序中,我写了这个

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为什么以这种方式检索序列值?

如果您有三个单独的语句:

  • 下特瓦尔

  • 柯尔瓦尔

  • 下特瓦尔

  • 那你就对了。但你只有两个

  • 下特瓦尔

  • 柯尔瓦尔和奈克特瓦尔

  • 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 ;
    

    只是为了跟进Christian的解释:

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


    本例中的“位置”是前面列表中的一项,“每个
    INSERT
    语句包含
    VALUES
    子句”

    谢谢你的及时回复。我这样修复了这个问题:将值(my_seq.CURRVAL-1,my_seq.NEXTVAL)插入依赖项(parent_question_id,child_question_id)。看来你的解决方案比我的更优雅。我想知道你对我的解决方案的看法。我绝对不会使用currval-1结构。当然,它是有效的(因为CURRVAL只为您的会话返回值-不存在其他会话会影响值的危险),但是想想那些可怜的开发人员,他们必须在2年内更新您的代码。除非你发表评论,否则他们不会知道你的意图。但是通过使用变量,你可以清楚地知道你想做什么——代码本身就有注释。非常感谢你,我明白了。我会更改它。@ChristianPalmer“不同的会话不会影响该值的危险”-当然,不同的会话可以在该会话中的两次调用之间调用
    nextval
    ;不能保证这两个会得到连续的值?我会避免这种构造,因为它并不总是有效的——而且可能需要很长一段时间才能真正起作用,然后很难找出哪里出了问题以及如何修复它……@ChristianPalmer-是的,是的,但在这种情况下(OP的评论),它与同一语句中的
    nextval
    是一样的(正如你的回答所解释的)因此,本次会话中第一次插入的
    nextval
    得到了42;其他一些会话增加了序列;本次会话中第二次插入的
    nextval
    得到了44。在该语句中
    currval
    现在也是44,因此
    currval-1
    是43-不是预期的/期望的42。是的,我们同意它不是好主意,我只是补充说,这比你的评论建议的要糟糕*8-)