我有一个大问题。我需要知道预言序列的下一个值而不改变它。
如果我使用sequence.NEXTVAL
,我会得到我需要的东西。问题是值改变了,所以下一条记录会得到这个值+1,这对我不利。
我知道我可以使用sequence.CURRVAL
,它很棒,因为它不会改变值,但在没有记录的情况下,它不起作用,在这种情况下,序列值可以是任何数字(不仅仅是 1 导致序列值钢存在)。
请帮我找到解决方案。
谢谢你变化很大!!!!
您绝对不应该依赖从不丢失序列中的值,因为它们针对顺序编号的并发性进行了优化。在很多情况下,数字可能会“丢失”。
此外,dba_sequences 中可见的值可能不是实际的下一个值,因为这些数字是从内存缓存中分配的。底层序列元数据表没有关于该缓存使用情况的数据。您还应该记住,在 RAC 系统中,每个实例都有自己的序列号缓存。
您可能会描述您要解决的问题,因为序列可能不适合您。
在多用户环境下是没有办法的。该值是 known - when you call.NEXTVAL
或unknown。序列不能被锁定。
查看“last_number”列
select * from USER_SEQUENCES
这仅在使用 nocache 选项创建序列时才有效。
因此,如果序列确实有缓存设置,请删除它并使用 nocache 重新创建它,然后您可以使用 user_sequences.last_number +1。
请注意,如果序列被大量使用,则会影响性能。另一方面,如果序列不使用那么多,那就没问题了。
没有编写应用程序(这是最好的解决方案),这是唯一的解决方案。
我看不出您想知道序列的下一个值的任何原因。该值的唯一重要性是当您将其用于新记录时。因此,您可以创建一条新记录并立即返回 ID 值:
declare
l_id number;
begin
Insert into table (id)
values (sequence.nextval)
return id into l_id;
-- and then do something more with the ID value
end;
或先获取一个新 ID,然后再使用
declare
l_id number;
begin
select sequence.nextval
into l_id
from dual;
-- then do something with the ID value
end;
好吧,我能给你的唯一建议是获取 nextval 然后恢复。但注意:仅当您的序列未从任何其他会话开始使用时,才执行这些操作。否则,如果在此操作期间从另一个会话中获取序列,则您可能永远无法恢复到原始值。所以在检查之前要小心:
在我的数据库中, seq_test 的当前值为 6
--获取下一个值
SQL> SELECT seq_test.NEXTVAL FROM dual;
NEXTVAL
----------
7
-- 好的,这是下一个值,现在恢复为原始值
SQL> ALTER SEQUENCE seq_test INCREMENT BY -1;
Sequence altered.
SQL> SELECT seq_test.NEXTVAL FROM dual;
NEXTVAL
----------
6
-- 恢复原始增量 by 子句
SQL> ALTER SEQUENCE seq_test INCREMENT BY 1;
Sequence altered.
- 查看
SQL> SELECT seq_test.CURRVAL FROM dual;
CURRVAL
----------
6
我再次警告你,这可能是致命的 ;-)