是否可以将模式中序列的当前值复制到另一个数据库?已在两个数据库中创建序列。这是在Oracle。
编辑:
根据以下帮助,一旦设置了数据库链接,此脚本将确保目标数据库序列值大于或等于源数据库值。这样做的动机是我们在复制数据后不会出现主键错误,因此目标数字不准确的事实没有问题。
set serveroutput on
DECLARE
CURSOR GetCursorsToSync
is
SELECT a.sequence_name, a.last_number last_number_a, b.last_number last_number_b
FROM user_sequences@SOURCE_DB a, user_sequences b
where a.sequence_name = b.sequence_name
and a.last_number != b.last_number;
type CursorsTableType is table of GetCursorsToSync%rowtype index by pls_integer;
CursorsTable CursorsTableType;
i pls_integer;
PROCEDURE reset_sequence(
sequence_name IN VARCHAR2,
source_value IN NUMBER,
target_value IN NUMBER )
IS
l_sql varchar2(4000);
l_temp number(30);
BEGIN
IF source_value <= target_value THEN
RETURN;
END IF;
dbms_output.put_line(sequence_name || ' ' || source_value || ' ' || target_value);
l_sql := 'alter sequence '|| sequence_name || ' increment by '||to_char(source_value-target_value);
dbms_output.put_line(l_sql);
EXECUTE immediate l_sql;
l_sql := 'SELECT '|| sequence_name || '.nextval FROM dual';
dbms_output.put_line(l_sql);
EXECUTE immediate l_sql into l_temp;
dbms_output.put_line(l_temp);
l_sql := 'alter sequence '|| sequence_name || ' increment by 1';
dbms_output.put_line(l_sql);
EXECUTE immediate l_sql;
COMMIT;
END reset_sequence;
BEGIN
open GetCursorsToSync;
fetch GetCursorsToSync bulk collect into CursorsTable;
close GetCursorsToSync;
commit;
i := CursorsTable.first;
while i is not null loop
reset_sequence(CursorsTable(i).sequence_name,
CursorsTable(i).last_number_a,CursorsTable(i).last_number_b);
i := CursorsTable.next(i);
end loop;
end;
/
答案 0 :(得分:4)
UltraCommits语句和数据库链接的组合,以及您可以安排自动运行的存储过程,将为您提供良好的服务。
--drop create db_link
DROP DATABASE LINK SOURCE_DB;
CREATE DATABASE LINK "SOURCE_DB"
CONNECT TO USER IDENTIFIED BY password USING 'SOURCE_DB';
--drop create sequences
DROP sequence target_seq;
CREATE sequence target_seq start with 6;
--the next two lines run in source db
DROP sequence source_seq;
CREATE sequence source_seq start with 6000;
--take a look at the sequences to get an idea of what to expect
SELECT source_schema.source_seq.nextval@SOURCE_DB source_seq,
target_seq.nextval target_seq
FROM dual;
--create procedure to reset target sequence that you can schedule to automatically run
CREATE OR REPLACE
PROCEDURE reset_sequence
AS
l_source_sequence pls_integer;
l_target_sequence pls_integer;
l_sql VARCHAR2(100);
BEGIN
SELECT source_schema.source_seq.nextval@SOURCE_DB,
target_seq.nextval
INTO l_source_sequence,
l_target_sequence
FROM dual;
l_sql := 'alter sequence target_seq increment by '||to_number(l_source_sequence-l_target_sequence);
EXECUTE immediate l_sql;
SELECT target_seq.nextval INTO l_target_sequence FROM dual;
l_sql := 'alter sequence target_seq increment by 1';
EXECUTE immediate l_sql;
COMMIT;
END reset_sequence;
/
--execute procedure to test it out
EXECUTE reset_sequence;
--review results; should be the same
SELECT source_schema.source_seq.nextval@SOURCE_DB, target_seq.nextval FROM dual;
答案 1 :(得分:0)
问题:我们如何在Oracle序列中设置LASTVALUE值? 答:您可以通过执行ALTER来更改Oracle序列的LASTVALUE SEQUENCE命令。 例如,如果Oracle序列使用的最后一个值为100,并且您希望重置序列以将225作为下一个值。您将执行以下命令。
alter sequence seq_name increment by 224;
select seq_name.nextval from dual;
alter sequence seq_name increment by 1;
现在,序列服务的下一个值将是225。
答案 2 :(得分:0)
我在尝试执行基于Reynold先生提供的脚本时遇到以下错误:
ORA-04013:CACHE的编号必须少于一个周期。
原因:给定CACHE的数量大于循环中的值。 行动:扩大周期,或缓存更少的值。
如果当前 nextval 太大而无法在当前周期中缓存指定数量的值,则会遇到此错误。因此,我已经包含了他的脚本的更新版本,其中首先使用“NOCACHE”选项更改目标序列,然后在更新目标 nextval 之后将缓存恢复为其原始值。在我的示例中,db-link和别名“PD”指的是源数据库,“QA”指的是目标数据库。
我希望这对以前的解决方案对我有帮助。
SET serveroutput ON
DECLARE
CURSOR GetCursorsToSync IS
SELECT pd.sequence_name, pd.last_number last_number_pd,
qa.last_number last_number_qa, qa.cache_size
FROM user_sequences@PD pd
JOIN user_sequences qa
on qa.sequence_name = pd.sequence_name
WHERE qa.last_number != pd.last_number;
TYPE CursorsTableType IS
TABLE OF GetCursorsToSync%ROWTYPE INDEX BY pls_integer;
CursorsTable CursorsTableType;
i pls_integer;
PROCEDURE Reset_Sequence(
sequence_name IN VARCHAR2,
source_value IN NUMBER,
target_value IN NUMBER,
cache_size IN NUMBER)
IS
l_sql VARCHAR2(4000);
l_temp NUMBER(30);
BEGIN
IF source_value <= target_value THEN
RETURN;
END IF;
dbms_output.put_line(sequence_name || ' ' || source_value || ' ' || target_value);
IF cache_size > 0 THEN
l_sql := 'alter sequence '|| sequence_name || ' nocache';
dbms_output.put_line(l_sql);
EXECUTE IMMEDIATE l_sql;
END IF;
l_sql := 'alter sequence '|| sequence_name || ' increment by ' || TO_CHAR(source_value-target_value);
dbms_output.put_line(l_sql);
EXECUTE IMMEDIATE l_sql;
l_sql := 'SELECT ' || sequence_name || '.nextval FROM dual';
dbms_output.put_line(l_sql);
EXECUTE IMMEDIATE l_sql INTO l_temp;
dbms_output.put_line(l_temp);
l_sql := 'alter sequence ' || sequence_name || ' increment by 1';
dbms_output.put_line(l_sql);
EXECUTE IMMEDIATE l_sql;
IF cache_size > 0 THEN
l_sql := 'alter sequence '|| sequence_name || ' cache ' || TO_CHAR(cache_size);
dbms_output.put_line(l_sql);
EXECUTE IMMEDIATE l_sql;
END IF;
COMMIT;
END Reset_Sequence;
BEGIN
OPEN GetCursorsToSync;
FETCH GetCursorsToSync BULK COLLECT INTO CursorsTable;
CLOSE GetCursorsToSync;
COMMIT;
i := CursorsTable.FIRST;
WHILE i IS NOT NULL LOOP
Reset_Sequence(CursorsTable(i).sequence_name, CursorsTable(i).last_number_pd,
CursorsTable(i).last_number_qa, CursorsTable(i).cache_size);
i := CursorsTable.NEXT(i);
END LOOP;
END;
/
答案 3 :(得分:0)
myFile