序列生成的号码不保存如何克服保留?

问题描述 投票:0回答:1

它具有生成用户输入的药品代码的序列 如果输入药品并撤消此过程,则该编号将已为未输入的该药品保留,因此下一个药品的编号将位于已保留的药品之后。

创建序列 F_SQ
从 1 开始
最大值 999999999999999999999999999
最小值 1
无循环
缓存 20;
我使用上面的脚本创建了一个序列。我们的夜间作业使用这些序列,因此第一个条目使用 1,2,3,4,5,下一个条目以 6 开头,如果用户不保存此条目,那么他想输入以 6 开头的项目7 ..等等

如何克服这个问题?

oracle plsql oracle-apex
1个回答
0
投票

如果您想要无间隙的序列号,该视频将介绍如何做到这一点

https://youtu.be/B5JltFoe5Ho

使用下面的代码。但正如其他人所说,甚至正如视频描述所说:“无间隙序列的第一条规则是......忘记它并允许间隙:-)”

无论如何,这是执行此操作的代码

create table seqs
  ( name   varchar2(100),
    constraint seqs_pk primary key ( name )
  )
organization index ;

insert into seqs
select 'SEQ'||rownum
from dual
connect by level <= 5;

select * from seqs;

create table seqs_numbers
  ( name   varchar2(100),
    num    number(10),
    state  varchar2(10),
    constraint seqs_numbers_pk primary key ( name,num ),
    constraint seqs_numbers_fk foreign key ( name) references seqs ( name ) on delete cascade,
    constraint seqs_numbers_ck check ( state in ('free','used'))
  )
organization index ;

insert into seqs_numbers
select s.name, num, 'free'
from   seqs s,
       ( select level num from dual 
         connect by level <= 1000 );
commit;

select * from seqs_numbers
where  name = 'SEQ1'
and    rownum <= 12;

create or replace
function get_seq(p_name varchar2) return number is
  l_seq number;
  cursor next_seq is
    select num
    from   seqs_numbers
    where  name = p_name
    and    state='free'
    order by num
    for update skip locked;
begin
  open next_seq;
  fetch next_seq into l_seq;
  close next_seq;
  update seqs_numbers
  set    state = 'used'
  where  name = p_name
  and    num = l_seq;
  
  return l_seq;
end;
/

set serverout on 
exec dbms_output.put_line(get_seq('SEQ1'));

select *
from   seqs_numbers
where  name = 'SEQ1'
and    num  <= 5;

exec dbms_output.put_line(get_seq('SEQ1'));

select *
from   seqs_numbers
where  name = 'SEQ1'
and    num  <= 5;

exec dbms_output.put_line(get_seq('SEQ1'));

select *
from   seqs_numbers
where  name = 'SEQ1'
and    num  <= 5;

declare
  pragma autonomous_transaction;
begin
  dbms_output.put_line(get_seq('SEQ1'));
  commit;
end;
/
rollback;

select *
from   seqs_numbers
where  name = 'SEQ1'
and    num  <= 5;

exec dbms_output.put_line(get_seq('SEQ1'));
commit;

select *
from   seqs_numbers
where  name = 'SEQ1'
and    num  <= 5;
© www.soinside.com 2019 - 2024. All rights reserved.