在多表插入中限制生成的序列值

Isa*_*man 2 oracle insert sequence

在 Oracle 中,给定以下对象:

create table a (x number );
create table b (val number );
create table c (val number );
create sequence my_seq;
Run Code Online (Sandbox Code Playgroud)

假设我a按如下方式填充表:

insert into a (x) values (1);
insert into a (x) values (2);
insert into a (x) values (3);
insert into a (x) values (4);
Run Code Online (Sandbox Code Playgroud)

使用 中的值a,我想填充表bc如下所示:当a.x为偶数时,从序列中生成一个新数字并插入my_seq.nextvalb.valand 中c.val;否则,将my_seq.currval(最近生成的值但不是新值)插入到c.val.

我目前拥有的是一个 insert all 语句,如下所示:

insert all 
    when mod(x,2) = 0 then
        into b (val) values (my_seq.nextval)
        into c (val) values (my_seq.currval)
    else 
        into c (val) values (my_seq.currval)
select x from a
Run Code Online (Sandbox Code Playgroud)

由于 Oracle 在 insert all 语句中对序列的处理是为子查询中返回的每一行生成一个新值,因此我将 4 个新生成的值插入到c. 我怎样才能达到我想要的行为,2 个新生成的值插入一次b和两次插入c

Phi*_*lᵀᴹ 5

这是不可能的,因为你正在混合curval并且nextval(顺便说一下,很高兴被证明是错误的)。您也不能使用WITH xxxx ASin INSERT ALL,这是我第一个想到的解决方法。

无论如何,这对您来说是一个合乎逻辑的解决方法:

insert all 
    when mod(x,2) = 0 then
        into b (val) values (my_seq.nextval/2)
        into c (val) values (trunc(my_seq.currval/2+0.5))
    else 
        into c (val) values (trunc(my_seq.currval/2+0.5))
select x from a;
Run Code Online (Sandbox Code Playgroud)

显然,如果您在其他代码中使用它,序列号总是会是您期望的两倍,但我假设这是一个 1-off 语句。