Oracle如何实现两个数据库的同步(用实体化视图实现)(oracle快照实例)(二)
定oracle自动在1分钟 (1/24*60)后进行第一次快速刷新,以后每隔10分钟 (10/24*60)快速刷新一次。)
或者
SQL > CREATE OR REPLACE PROCEDURE sp_snapshot_refresh
IS
BEGIN
DBMS_REFRESH.MAKE ( NAME=>'快照名', LIST=>'snap.表1, 'snap.表2', 'snap.表3', NEXT_DATE=>TRUNC (SYSDATE+1)+2/24, INTERVAL=>'(SYSDATE+1)', IMPLICIT_DESTROY=>FALSE, LAX=>TRUE);
END; /
SQL > EXECUTE sp_snapshot_refresh
这样就创建了一个定时任务来每天早晨2:00定时刷新快照。运行下面的SQL语句就可以看到刚刚加入的这个任务。
SQL > SELECT JOB, WHAT FROM DBA_JOBS;
6. 在用户db3下创建快照的私有同义词:
SQL > CREATE SYNONYM db3.表1 FOR db2.表1;
7. 以db2用户向db3用户授与快照可以select的权限。
SQL > GRANT SELECT ON 表1 TO db3;
同样的步骤在位置3(ora_db2)和位置4(ora_db3)建立位置1(ora_db1)的代码表快照和定时刷新任务。这样就可实现在位置1统一维护代码表,在位置2、3和4使用该代码表的目的。如下面的SQL语句,在位置2(ora_db2)用户UserB浏览在位置1(ora_db1)中的代码表。
SQL > SELECT * FROM 表1;
二、日常维护
无论任何时候只要出现网络连接问题,刷新就会失败。这些错误信息可以在alert log文件中找到。下面简单介绍一下对这种问题的处理办法:
1. 首先在任务队列中找到刷新快照的的任务编号
SQL > SELECT JOB,what FROM DBA_JOBS;
2. 删除该任务
SQL > EXECUTE DBMS_JOB.REMOVE (JOBNO);
3. 删除快照组
SQL >drop snapshot 快照1;
4. 重新创建快照组并且重新定时任务来定时刷新快照
SQL > EXECUTE sp_snapshot_refresh
五、快照监视
快照可以通过下面的SQL语句来监视
SQL > SELECT NAME,
TO_CHAR(last_refresh,'DD-MON-YY HH:MM:SS')
FROM DBA_SNAPSHOTS;
补充:
--1修改会话时间格式
ALTER SESSION SET NLS_DATE_FORMAT = ''YYYY-MM-DD HH24:MI:SS'';
--2.查看快照最后一次刷新时间
SELECT NAME,LAST_REFRESH FROM ALL_SNAPSHOT_REFRESH_TIMES;
--3.查看快照下次执行时间
select last_date,next_date,what from user_jobs order by next_date;
dbms_output.put_line(''use ''||''plsql'');
create or replace trigger TRI_test_user_AFR
after insert or update or delete on sn_test_user
for each row
begin
if deleting then
delete from test_user where id=:old.id;
end if;
if inserting then
insert into test_user(id,name)
values(:new.id,:new.name);
end if;
if updating then
update test_user set name=:new.name where id=:old.id;
end if;
end TRI_test_user_AFR;
--6.如果你想双向同步,请在源数据库中执行前6步,并在双方都创建以下触发器(当源数据库表改变时,目的数据库表跟着改变,目的数据库表改变时,源数据库表也改变)
CREATE OR REPLACE TRIGGER BST114.TRI_TEST_USER_AFR
AFTER DELETE OR INSERT OR UPDATE
ON BST114.SN_TEST_USER
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
declare
tmp_id number(10):=-1;
begin
dbms_output.put_line(''begin'');
if inserting then
--select id into tmp_id from test_user where id=:new.id;
for p in(select id from test_user where id=:new.id)
loop
tmp_id:=p.id;
end loop;
dbms_output.put_line(tmp_id||''===------------'');
if (tmp_id=-1) then
insert into test_user(id,name,age)
values(:new.id,:new.name,:new.age);
end if;
end if;
if updating then
dbms_output.put_line(''updated'');
for p in(select name,age from test_user where id=:old.id)
loop
if (p.name!=:new.name) or (p.age!=:new.age) then
update test_user set name=:new.name,age=:new.age where id=:old.id;
end if;
end loop;
end if;
if deleting then
dbms_o