Oracle “生成始终作为标识”将 21 作为序列值

Oracle "generated always as identity" gives 21 as sequence value

提问人:sunleo 提问时间:3/21/2023 最后编辑:sunleo 更新时间:3/21/2023 访问量:212

问:

Oracle 序列给出的是 21 而不是 3。我不知道为什么是 21 而不是其他值。请帮助理解这一点。

更新我将此序列用于静态引用表,以便 id 可用于 java 代码来提取数据,这些数据应该按 1 、1+1、1+2 等顺序排列。

create table table1 (id number(20) generated always as identity, name varchar2(20)); 
insert into table1(name) values('111');
insert into table1(name) values('222');
select * from table1;
--Output
1   111
2   222
insert into table1(name) values('333');
select * from table1;
21  333 -- problamatic id as 21 generated
1   111
2   222
SQL Oracle 序列

评论

4赞 Alex Poole 3/21/2023
默认情况下,序列是缓存的(有充分的理由)而不是排序的,并且各种事情都可能导致间隙(例如回滚);如果您使用的是 RAC,则每个节点都有自己的缓存,因此您可以获取交错值。这很正常。序列不应该是无间隙的,也不一定是按时间顺序排列的(即使存在 21 个,您的下一个插入现在也可能得到 3 个)。如果你需要知道插入发生的顺序,那么你可以让它有序,或者时间戳列可能效果更好。但这取决于你为什么认为它有问题。

答:

3赞 Littlefoot 3/21/2023 #1

标识列基于序列值在后台。序列保证了唯一性,但它们返回的值不是/不必是无间隙的。

为什么你觉得这是“有问题”的价值?这是怎么回事?它与任何其他价值一样好。21

如果要选择期间返回无间隙值,请包括例如 分析功能:row_number

select row_number() over (order by id) rn,      --> this
       name
from table1;

并将其呈现给用户。离开是为了你自己的目的,当你必须通过它访问行时。无论如何,最终用户都不关心 ID。ID


你评论说你

想要按顺序获取值,但没有发生

“我想要”没有多大帮助。你为什么想要它?你期望有什么好处?

有一种方法可以创建无间隙的数字序列,但是(据我所知)它需要一些编程。

此外,当您删除该序列中间的某一行时,也会出现问题。然后呢?你会再次得到一个差距。你会重新排序所有数字吗?您可以(理论上),但是 - 如果有引用该 ID 的外键怎么办?修改主键值很少是一个好主意。

简而言之:不要做任何事情。接受序列是唯一的,可能存在差距,然后继续前进。

评论

0赞 sunleo 3/21/2023
感谢您的回复,但我想按顺序获取值,但这没有发生。