如何检索oracle序列的当前值而不递增它?

wb1gzix0  于 2022-12-29  发布在  Oracle
关注(0)|答案(7)|浏览(150)

是否有一个SQL指令来检索不递增序列的值。
谢谢。

    • 编辑和结论**

正如Justin Cave所说,尝试"保存"序列号是没有用的

select a_seq.nextval from dual;

足以检查序列值。
我仍然认为奥利的回答是好的,因为它回答了最初的问题。但是如果你想修改序列,问问自己不修改序列的必要性。

uurv41yg

uurv41yg1#

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>';
    • 编辑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,然后再将其恢复为原始值,以确保没有缓存大量值。

tkclm6bt

tkclm6bt2#

第一个月
请记住,只有在当前会话中运行select MY_SEQ_NAME.nextval from DUAL;时,它才起作用。

1zmg4dgp

1zmg4dgp3#

以下是常用的:

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

但是下面的代码可以将序列更改为您所期望的。1可以是整数(负或正)

alter sequence field_SQ increment by 1 minvalue 0
iqjalb3h

iqjalb3h4#

这不是一个答案,真的,我会输入它作为一个评论的问题没有被锁定。这回答了问题:
你为什么想要它?
假设您有一个以序列作为主键的表,并且序列是由插入触发器生成的。如果您希望序列可用于记录的后续更新,则需要有一种方法来提取该值。
为了确保得到正确的查询,您可能希望将INSERT和RonK的查询 Package 在一个事务中。
RonK的疑问:

select MY_SEQ_NAME.currval from DUAL;

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

j7dteeu8

j7dteeu85#

我还尝试使用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 ...是一个很好的解决方案,简单而快速,前提是您的序列已链接到该表
2uluyalo

2uluyalo6#

如果您的用例是某个后端代码插入一条记录,然后同一代码希望检索最后一个插入id,而不指望任何底层数据访问库预设函数来完成此操作,那么,正如其他人提到的,您应该使用SEQ_MY_NAME.NEXTVAL为所需列(通常是主键)创建SQL查询,然后从后端运行语句SELECT SEQ_MY_NAME.CURRVAL FROM dual
记住,CURRVAL只有在NEXTVAL已经被调用过的情况下才是可调用的,这在上面的策略中是很自然的...

xmjla07d

xmjla07d7#

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

SELECT mysequence.CURRVAL INTO v_myvariable FROM DUAL;

遗憾的是,如果您没有在会话中修改序列,我相信其他人说NEXTVAL是唯一的出路是正确的。

相关问题