我可以在 Oracle 中实现“无缝”标识列吗?

ber*_*d_k 1 oracle identity

在 SQL Server 中很容易编写:

create table #tmp (
    id      integer identity(1,1) primary key,
    message varchar(256)
);
Run Code Online (Sandbox Code Playgroud)

当我尝试将其迁移到 Oracle 时,我最终得到:

CREATE GLOBAL TEMPORARY TABLE tmp(
    id integer primary key,
    message varchar2(256)
) ON COMMIT PRESERVE ROWS;

CREATE SEQUENCE S_TMP_ID START WITH 1;

CREATE OR REPLACE TRIGGER TR_TMP 
BEFORE INSERT ON tmp
FOR EACH ROW
WHEN (new.id IS NULL)
BEGIN
  SELECT S_TMP_ID.NEXTVAL
  INTO   :new.id
  FROM   dual;
END;
/
Run Code Online (Sandbox Code Playgroud)

好的。我得到了独特的、不断增加的 id 值。但是,当两个会话同时使用同一个全局临时表时,我的想法序列就会出现差距,并且它们以某个任意值开始。

任何想法如何为全局临时表创建更好的标识值?

Jac*_*las 5

保证无间隙系列(假设没有删除)的唯一方法是序列化- 几乎总是一个坏主意

使用序列或身份,您不能假设您的系列将像@a_horse 提到的那样无间隙 - 但看起来您假设即使有间隙,序列顺序和插入顺序之间也存在某种关系 - 这也不是真的!可以较低的序列号之前插入较高的序列号。因此试图加入“连续”行是一个毫无意义的概念

例子:

create sequence seq;
create table t1(id integer);
create table t2(id integer);

--session 1:
insert into t1 select seq.nextval from dual connect by level<1000000;
commit;

--session 2:
insert into t2 select seq.nextval from dual connect by level<1000000;
commit;
Run Code Online (Sandbox Code Playgroud)

结果:

select min(id), max(id) from t1 union all select min(id), max(id) from t2;

MIN(ID)                MAX(ID)                
---------------------- ---------------------- 
1                      1671679                
356547                 1999998               
Run Code Online (Sandbox Code Playgroud)