我正在尝试创建一个脚本来将数据从一个数据库迁移到另一个数据库.我目前无法做的一件事是将序列的nextval设置为另一个DB中序列的nextval.
我从user_sequences中获得了值的差异,并生成了以下动态sql语句:
execute immediate 'alter sequence myseq increment by 100'; execute immediate 'select myseq.nextval from dual'; execute immediate 'alter sequence myseq increment by 1'; commit;
但没有任何反应.我错过了什么?如果我在程序之外运行相同的语句,它们可以正常工作:
alter sequence myseq increment by 100; select myseq.nextval from dual; alter sequence myseq increment by 1; commit;
编辑:向所有人道歉,不清楚.我实际上正在改变同一个DB中的序列.我只是从远程数据库中获取值.也许没必要提到远程数据库,因为它不会影响事物.我只提到它来解释我的目标是什么.
步骤1.我从远程DB获取序列的nextval.
select (select last_number from dba_sequences@remoteDB where upper(sequence_name) = upper(v_sequence_name)) - (select last_number from user_sequences where upper(sequence_name) = upper(v_sequence_name)) increment_by from dual;
execute immediate 'alter sequence myseq increment by 100'; execute immediate 'select myseq.nextval from dual'; execute immediate 'alter sequence myseq increment by 1'; commit;
没有错误,但没有发生任何事情.当我用DBMS_OUTPUT.PUT_LINE编写sql语句并在外面运行它们时它们工作了.
解决方法
现在您已经在这里正确解释了您的要求是一些代码.我写了这个,所以它适用于你的架构中的任何序列.
create or replace procedure resync_seq (p_seq_name in user_sequences.sequence_name%type) is local_val pls_integer; remote_val pls_integer; diff pls_integer; begin execute immediate 'select '|| p_seq_name ||'.nextval from dual' into local_val; select last_number into remote_val from user_sequences@remote_db where sequence_name = p_seq_name ; diff := remote_val - local_val; if diff > 0 then execute immediate 'alter sequence '|| p_seq_name ||' increment by ' ||to_char(diff); execute immediate 'select '|| p_seq_name ||'.nextval from dual' into local_val; execute immediate 'alter sequence '|| p_seq_name ||' increment by 1'; end if; end;
该过程不需要COMMIT,因为DDL语句发出隐式提交(实际上是两个).
您可以执行它并查看这样的同步值(在sql * PLus中):
exec resync_seq('MYSEQ') select myseq.currval from dual