Мой подход - небольшое расширение Пример Дугмана .
Расширения ...
Передать начальное значение в качестве параметра. Зачем? Мне нравится называть эту вещь сбросом последовательности обратно к максимальному идентификатору, используемому в некоторой таблице . В итоге я вызываю этот процесс из другого скрипта, который выполняет несколько вызовов для целой группы последовательностей, сбрасывая nextval обратно до некоторого уровня, который достаточно высок, чтобы не вызывать нарушений первичного ключа, когда я использую значение последовательности для уникального идентификатора.
Это также чтит предыдущее минимальное значение . Фактически может выдвинуть следующее значение еще выше , если желаемое p_val или существующее минимальное значение выше текущего или рассчитанного следующего значения.
Лучше всего, его можно вызвать, чтобы сбросить до указанного значения, и просто подождать, пока в конце не появится процедура «исправить все мои последовательности».
create or replace
procedure Reset_Sequence( p_seq_name in varchar2, p_val in number default 0)
is
l_current number := 0;
l_difference number := 0;
l_minvalue user_sequences.min_value%type := 0;
begin
select min_value
into l_minvalue
from user_sequences
where sequence_name = p_seq_name;
execute immediate
'select ' || p_seq_name || '.nextval from dual' INTO l_current;
if p_Val < l_minvalue then
l_difference := l_minvalue - l_current;
else
l_difference := p_Val - l_current;
end if;
if l_difference = 0 then
return;
end if;
execute immediate
'alter sequence ' || p_seq_name || ' increment by ' || l_difference ||
' minvalue ' || l_minvalue;
execute immediate
'select ' || p_seq_name || '.nextval from dual' INTO l_difference;
execute immediate
'alter sequence ' || p_seq_name || ' increment by 1 minvalue ' || l_minvalue;
end Reset_Sequence;
Эта процедура полезна сама по себе, но теперь давайте добавим еще одну, которая вызывает ее и задает все программно с соглашением об именах последовательностей и ищет максимальное значение, используемое в существующей таблице / поле ...
create or replace
procedure Reset_Sequence_to_Data(
p_TableName varchar2,
p_FieldName varchar2
)
is
l_MaxUsed NUMBER;
BEGIN
execute immediate
'select coalesce(max(' || p_FieldName || '),0) from '|| p_TableName into l_MaxUsed;
Reset_Sequence( p_TableName || '_' || p_Fieldname || '_SEQ', l_MaxUsed );
END Reset_Sequence_to_Data;
Теперь мы готовим на газе!
Приведенная выше процедура проверит максимальное значение поля в таблице, построит имя последовательности из пары таблица / поле и вызовет "Reset_Sequence" с этим измеренным максимальным значением.
Последняя часть этой головоломки и глазурь на пироге идут дальше ...
create or replace
procedure Reset_All_Sequences
is
BEGIN
Reset_Sequence_to_Data( 'ACTIVITYLOG', 'LOGID' );
Reset_Sequence_to_Data( 'JOBSTATE', 'JOBID' );
Reset_Sequence_to_Data( 'BATCH', 'BATCHID' );
END Reset_All_Sequences;
В моей фактической базе данных есть около сотни других последовательностей, сбрасываемых с помощью этого механизма, поэтому в этой процедуре выше 97 вызовов Reset_Sequence_to_Data .
Нравится это? Ненавидеть это? Безразлично