0

我有一个包含多个插入的脚本(可能会失败),其中包括 nextval 作为

insert into table a (id, value) (id_seq.nextval, 'value');
...

如果脚本失败并且我回滚插入,则序列不会回滚并且不会使用多个 id

是否有最佳实践来避免多次插入序列中的“丢失”ID?

我发现了类似的问题,但在不同的背景下

4

3 回答 3

2

无法自动回滚序列。和往常一样,你不需要那个。

于 2019-08-28T06:21:18.547 回答
2

ROLLBACK适用于DML. 它消除了当前事务中发生的表中任何数据更改的影响。

ROLLBACK不能将序列值更改为其原始值(事务开始时的序列值)。

无论如何,Sequence它只是一个递增的数字,如果它滑过几个数字,您不会丢失任何宝贵的数据,除非您的项目需要一个连续的序列并且这是严格的要求。如果是这样,那么您必须找到其他解决方法。

您无法控制序列中的间隙。

干杯!!

于 2019-08-28T06:28:40.660 回答
1

无法设置现有序列的当前值。如果您需要更改序列的值(当前值),您必须“增加它”或重新创建它。

“递增”(肮脏的解决方法):

-- current value is 100
ALTER SEQUENCE seq_x  INCREMENT BY -25;--number of wrong increments or max(id)-seq_x.nextval in a procedure
SELECT seq_x.NEXTVAL FROM dual; -increments by 1 step, in this case -25
-- -> new current value is 75
ALTER SEQUENCE seq_x INCREMENT BY 1;

重新创建它:

DROP SEQUENCE seq_x;
CREATE SEQUENCE seq_x INCREMENT BY 1 START WITH 75;-- desired start value
-- You need to reassign privileges, if some were given

如果您使用的是自动增量列,则可以使用将其设置为表中的最高值

ALTER TABLE table_name MODIFY ID GENERATED ALWAYS AS IDENTITY (START WITH LIMIT VALUE);
-- customize as you need it, i.e. GENERATED BY DEFAULT instead of GENERATED ALWAYS

如果出于某种原因总是需要最后一个值,则必须MAX(id)从给定的表中进行选择。但是:表中缺少 id 不会影响性能或其他任何东西,它只会伤害一些人的眼睛 :)

于 2019-08-28T06:51:20.497 回答