我做了以下触发器:
create or replace trigger TSM_ENTITY_TRG
before insert on TSM_ENTITY
for each row
begin
select TSM_ENTITY_ID_SEQ.nextval
into :new.ID
from dual;
end;
/
代码中的序列是
CREATE SEQUENCE TSM_ENTITY_ID_SEQ
MINVALUE 12
START WITH 12
INCREMENT BY 1;
触发器按需要工作,除了一件事,如果我删除一行,则触发器继续向行添加增量。例如,行的id将是12然后下一个将是13然后是14然后是15.然后,假设我删除了第15行并在之后添加了新行。然后行ID将被列为12然后是13然后是14然后是16.有没有办法让序列或触发器检测到间隙并填充它?
答案 0 :(得分:0)
没有。由序列填充的列将具有间隙。如果您的要求是无间隙值,则不能使用序列。
如果你真的,真的认为你需要一个无间隙的值集,那么你必须引入一个序列化机制,确保一次只有一个用户将数据插入表中。这是可能的。但它从根本上降低了应用程序的可伸缩性和性能。并且它会大大增加您在遇到维护问题的可能性,例如在持有DBA必须找到并在任何人继续工作之前杀死的锁定而死亡的会话。我从未遇到过这样一种情况:商业用户在听到产生无差距价值的缺点后,决定他们真的想要承担这些费用。
如果您只想查看查询中的无间隙值集,可以使用rank
等分析函数
SELECT rank() over (order by id) gap_free_rank
FROM tsm_entity;
答案 1 :(得分:0)
这是一个坏主意,您必须忽略主键的值。这个值只需要检测值指向的行。
作为您的任务的解决方案:
我们假设我们有这种表结构:
create table TSM_ENTITY (
id NUMBER(10),
code VARCHAR2(20 char),
name VARCHAR2(20 char)
);
然后您可以根据表格创建视图:
CREATE VIEW TSM_ENTITY_V AS
SELECT ROW_NUMBER() over(order by id) AS id, t.code, t.name
FROM TSM_ENTITY t
ROW_NUMBER()函数为您提供连续的数字范围。