我的方法是对Dougman's example 进行小范围扩展。
扩展是...
传入种子值作为参数。为什么?我喜欢称将序列重置为某些表中使用的最大 ID。我最终从另一个脚本调用这个过程,该脚本对一大堆序列执行多次调用,将 nextval 重置回某个足够高的级别,在我使用序列的值作为唯一标识符的情况下不会导致主键违规。
它还尊重以前的最小值。如果所需的 p_val 或 现有最小值 高于当前或计算的下一个值,它实际上可能 将下一个值推得更高。 p>
最重要的是,可以调用它来重置为指定值,然后等到最后看到包装器“修复我的所有序列”过程。
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。
喜欢吗?讨厌它?冷漠?