182

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

谢谢。

编辑和结论

正如贾斯汀洞穴所说,尝试“保存”序列号没有用,所以

select a_seq.nextval from dual;

足以检查序列值。

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

4

7 回答 7

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

user_sequences您可以从和获取各种序列元all_sequences数据dba_sequences

这些视图跨会话工作。

编辑:

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

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

如果您想要所有元数据,那么:

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

希望能帮助到你...

编辑2:

如果您的缓存大小不是 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在重置之前将缓存设置为,然后再将其恢复为原始值,以确保您没有缓存很多值。

于 2012-04-18T13:22:39.687 回答
138

select MY_SEQ_NAME.currval from DUAL;

请记住,它仅在您select MY_SEQ_NAME.nextval from DUAL;在当前会话中运行时才有效。

于 2012-04-18T13:23:12.057 回答
7

The follows is often used:

select field_SQ.nextval from dual;  -- it will increase the value by 1 for each run
select field_SQ.currval from DUAL;

However the following is able to change the sequence to what you expected. The 1 can be an integer (negative or positive)

alter sequence field_SQ increment by 1 minvalue 0
于 2020-09-17T13:15:20.780 回答
2

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

你为什么要它?

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

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

RonK 的查询:

select MY_SEQ_NAME.currval from DUAL;

在上述场景中,RonK 的警告不适用,因为插入和更新将发生在同一个会话中。

于 2019-03-28T18:39:38.523 回答
1

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

我不介意序列中的间隙,但就我而言,我正在考虑进行很多轮询,并且我讨厌非常大的间隙的想法。特别是如果一个简单的 SELECT 也一样快。

结论:

  • CURRVAL 非常没用,因为它不会从另一个会话中检测到 NEXTVAL,它只会返回您从之前的 NEXTVAL 中已经知道的内容
  • SELECT MAX(...) FROM ... is a good solution, simple and fast, assuming your sequence is linked to that table
于 2019-08-14T17:44:01.107 回答
1

If your use case is that some backend code inserts a record, then the same code wants to retrieve the last insert id, without counting on any underlying data access library preset function to do this, then, as mentioned by others, you should just craft your SQL query using SEQ_MY_NAME.NEXTVAL for the column you want (usually the primary key), then just run statement SELECT SEQ_MY_NAME.CURRVAL FROM dual from the backend.

Remember, CURRVAL is only callable if NEXTVAL has been priorly invoked, which is all naturally done in the strategy above...

于 2020-10-21T21:19:09.257 回答
-2

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

SELECT mysequence.CURRVAL INTO v_myvariable FROM DUAL;

可悲的是,如果您没有在会话中修改序列,我相信其他人说 NEXTVAL 是唯一的方法是正确的。

于 2017-09-12T20:00:40.297 回答