如何在不增加的情况下检索oracle序列的当前值?

时间:2012-04-18 13:20:58

标签: sql oracle sequence

是否有SQL指令来检索不增加它的序列的值。

感谢。

编辑和结论

如Justin Cave所述,尝试“保存”序列号是没有用的

select a_seq.nextval from dual;

足以检查序列值。

我仍然保持奥利的回答是好的,因为它回答了最初的问题。但要问问自己,如果你想要这样做,就不必修改序列。

7 个答案:

答案 0 :(得分:152)

SELECT last_number
  FROM all_sequences
 WHERE sequence_owner = '<sequence owner>'
   AND sequence_name = '<sequence_name>';

您可以从user_sequencesall_sequencesdba_sequences获取各种序列元数据。

这些视图适用于各个会话。

修改

如果序列在您的默认架构中,则:

SELECT last_number
  FROM user_sequences
 WHERE sequence_name = '<sequence_name>';

如果您想要所有元数据:

SELECT *
  FROM user_sequences
 WHERE sequence_name = '<sequence_name>';

希望它有所帮助...

<强> EDIT2:

如果缓存大小不是1,那么可靠的方法是:

SELECT increment_by I
  FROM user_sequences
 WHERE sequence_name = 'SEQ';

      I
-------
      1

SELECT seq.nextval S
  FROM dual;

      S
-------
   1234

-- Set the sequence to decrement by 
-- the same as its original increment
ALTER SEQUENCE seq 
INCREMENT BY -1;

Sequence altered.

SELECT seq.nextval S
  FROM dual;

      S
-------
   1233

-- Reset the sequence to its original increment
ALTER SEQUENCE seq 
INCREMENT BY 1;

Sequence altered.

请注意,如果其他人在此期间使用该序列 - 他们(或您)可能会

ORA-08004: sequence SEQ.NEXTVAL goes below the sequences MINVALUE and cannot be instantiated

此外,您可能希望在重置之前将缓存设置为NOCACHE,然后再将其恢复为原始值,以确保您没有缓存很多值。

答案 1 :(得分:114)

select MY_SEQ_NAME.currval from DUAL;

请注意,只有在当前会话中运行select MY_SEQ_NAME.nextval from DUAL;时,它才有效。

答案 2 :(得分:0)

我的原始回复事实上是不正确的,我很高兴它被删除了。下面的代码将在以下条件下工作:a)您知道没有其他人修改过序列b)您的会话修改了序列。在我的情况下,我遇到了一个类似的问题,我在调用一个修改值的过程,我相信这个假设是正确的。

SELECT mysequence.CURRVAL INTO v_myvariable FROM DUAL;

可悲的是,如果您没有修改会话中的顺序,我相信其他人都说正确的方式是NEXTVAL。

答案 3 :(得分:0)

这不是答案,真的,如果问题没有被锁定,我将其作为评论输入。回答了这个问题:

您为什么要它?

假设您有一个表,其中的序列作为主键,并且该序列是由插入触发器生成的。如果要使序列可用于记录的后续更新,则需要一种方法来提取该值。

为了确保您获得正确的答案,您可能希望将INSERT和RonK的查询包装在事务中。

RonK的查询:

select MY_SEQ_NAME.currval from DUAL;

在上述情况下,RonK的警告不适用,因为插入和更新将在同一会话中进行。

答案 4 :(得分:0)

我还尝试使用CURRVAL,以查找某些进程是否以该序列作为主键将新行插入到某些表中。我的假设是CURRVAL是最快的方法。但是a)CurrVal不起作用,因为您正在另一个Oracle会话中,所以它只会获得旧值,直到您在自己的会话中执行NEXTVAL为止。 b)select max(PK) from TheTable也非常快,可能是因为PK总是被索引。或select count(*) from TheTable。我仍在尝试,但两个SELECT似乎都很快。

我不介意序列中存在差距,但是就我而言,我正在考虑进行大量轮询,并且我讨厌存在很大差距的想法。尤其是如果简单的SELECT一样快。

结论:

  • CURRVAL几乎没有用,因为它不会从另一个会话中检测到NEXTVAL,它只会返回您以前的NEXTVAL中已经知道的内容
  • 假设您的序列已链接到该表,那么SELECT MAX(...)FROM ...是一个很好的解决方案,简单而又快速

答案 5 :(得分:0)

经常使用以下内容:

select field_SQ.nextval from dual;
select field_SQ.currval from DUAL;

但是,以下内容可以将顺序更改为您期望的顺序。 1可以是整数(负数或正数)

alter sequence field_SQ increment by 1 minvalue 0

答案 6 :(得分:-1)

如果您的用例是某些后端代码插入一条记录,那么同一代码想要检索最后一个插入ID,而无需依靠任何底层数据访问库预设函数来执行此操作,那么,正如其他人所提到的,应该只使用SEQ_MY_NAME.NEXTVAL编写所需列(通常是主键)的SQL查询,然后从后端运行语句SELECT SEQ_MY_NAME.CURRVAL FROM dual

请记住,仅在事先调用NEXTVAL的情况下才可以调用CURRVAL,这在上述策略中自然而然地完成了。