【发布时间】:2016-10-17 13:58:20
【问题描述】:
我在这里遇到了一个奇怪的情况。我使用触发器和序列来实现自动增量。我从使用 Hibernate 的 Web 应用程序将数据插入到我的表中。我在我的机器 (Netbeans) 以及我的办公室网络上测试网络应用程序(网络应用程序也使用 Wildfly 部署在我们的服务器上)。
它一直运行良好,直到由于唯一约束(主键)而开始出现异常。然后我发现问题出在为 id 生成值的序列上。例如,对于我的表 xtable,它的序列的 last_number 是 78400,xtable 中的最大 id 是 78308,但是序列的 nextval 是 78304。我不知道这是怎么发生的,因为我创建了以下序列:
CREATE SEQUENCE XTABLE_SEQUENCE INCREMENT BY 1 START WITH 1;
我尝试了以下方法来更新序列并使其 NEXTVAL 大于表中的 max(id),但在 n 次插入后我仍然得到相同的结果
declare
maxval number(10);
begin
select max(ID) into maxval from XTABLE;
maxval := maxval+1;
execute immediate 'DROP SEQUENCE XTABLE_SEQUENCE';
execute immediate 'CREATE SEQUENCE XTABLE_SEQUENCE START WITH '|| maxval+50 ||' INCREMENT BY 1';
end;
这里是触发语句:
create or replace TRIGGER xtable_sequence_tr
BEFORE INSERT ON xtable FOR EACH ROW
WHEN (NEW.id IS NULL)
BEGIN
SELECT xtable_sequence.NEXTVAL INTO :NEW.id FROM DUAL;
END;
或者为了避免我面临的问题,在 Oracle 中实施自动增量的正确方法是什么?在某些时候,由于(我不知道出于什么原因)表中的最大 id 恰好大于触发器中使用的 sequence.nextval ,我开始在主键上违反唯一键约束。是什么原因造成的以及如何解决?
【问题讨论】:
-
如果您重新创建序列但使用
nocache,而不是cache 100,会发生什么情况?另外,您的数据库是 RAC 数据库吗? -
您提到了触发器。请向我们展示他们的内容。还有hibernate生成的sql语句
-
你写了
Its sequence's last_number is 78400, the max id in xtable is 78308, but the sequence's nextval is 78304.但是Oracle序列不能回滚nextval值。你是手动改的吗? -
@KonstantinSorokin 这里是hibernate Hibernate生成的sql语句:insert into ADMIN.XTABLE(COL0,COL1,COL2,COL3,COL4,COL5,ID)值(?,?,?,?, ?, ?, ?)
-
您可以使用自治事务将触发器接收到的参数记录到日志表中。也许它从未发射过。
标签: java oracle triggers sequence auto-increment