1. 本實例已完全通過測試,單向,又向同步都可使用.
  2. --名詞說明:源——被同步的數據庫
  3.             目的——要同步到的數據庫
  4. 前6步必須執行,第6以后是一些輔助信息.
  5. --1、在目的數據庫上,創建dblink
  6. drop public database link dblink_orc92_182;
  7. Create public DATABASE LINK dblink_orc92_182 CONNECT TO bst114 IDENTIFIED BY password USING ''orc92_192.168.254.111'';
  8. --dblink_orc92_182 是dblink_name
  9. --bst114 是 username
  10. --password 是 password
  11. --''orc92_192.168.254.111'' 是遠程數據庫名
  12. --2、在源和目的數據庫上創建要同步的表(最好有主鍵約束,快照才可以快速刷新)
  13. drop table test_user;
  14. create table test_user(id number(10) primary key,name varchar2(12),age number(3));
  15. --3、在目的數據庫上,測試dblink
  16. select * from test_user@dblink_orc92_182;    //查詢的是源數據庫的表
  17. select * from test_user;
  18. --4、在源數據庫上,創建要同步表的快照日志
  19. Create snapshot log on test_user;
  20. --5、創建快照,在目的數據庫上創建快照
  21. Create snapshot sn_test_user as select * from test_user@dblink_orc92_182;
  22. --6、設置快照刷新時間(只能選擇一種刷新方式,推薦使用快速刷新,這樣才可以用觸發器雙向同步)
  23. 快速刷新
  24. Alter snapshot sn_test_user refresh fast Start with sysdate next sysdate with primary key;
  25. --oracle馬上自動快速刷新,以后不停的刷新,只能在測試時使用.真實項目要正確權衡刷新時間.
  26. 完全刷新
  27. Alter snapshot sn_test_user refresh complete Start with sysdate+30/24*60*60 next sysdate+30/24*60*60;
  28. --oracle自動在30秒后進行第一次完全刷新,以后每隔30秒完全刷新一次
  29. --7、手動刷新快照,在沒有自動刷新的情況下,可以手動刷新快照.
  30. 手動刷新方式1
  31. begin
  32. dbms_refresh.refresh(''sn_test_user'');
  33. end;
  34. 手動刷新方式2
  35. EXEC DBMS_SNAPSHOT.REFRESH(''sn_test_user'',''F'');  //第一個參數是快照名,第二個參數 F 是快速刷新 C 是完全刷新.
  36. --8.修改會話時間格式
  37. ALTER SESSION SET NLS_DATE_FORMAT = ''YYYY-MM-DD HH24:MI:SS'';
  38. --9.查看快照最后一次刷新時間
  39. SELECT NAME,LAST_REFRESH FROM ALL_SNAPSHOT_REFRESH_TIMES;
  40. --10.查看快照下次執行時間
  41. select last_date,next_date,what from user_jobs order by next_date;
  42. --11.打印調試信息
  43. dbms_output.put_line(''use ''||''plsql'');
  44. --12.如果你只想單向同步,那么在目的數據庫創建以下觸發器(當源數據庫表改變時,目的數據庫表跟著改變,但目的數據庫表改變時,源數據庫表不改變).
  45. create or replace trigger TRI_test_user_AFR
  46.   after  insert or update or delete on sn_test_user
  47.   for each row
  48. begin
  49.   if deleting then
  50.       delete from test_user where id=:old.id;
  51.   end if;
  52.   if inserting then
  53.       insert into test_user(id,name)
  54.       values(:new.id,:new.name);
  55.   end if;
  56.   if updating then
  57.      update test_user set name=:new.name where id=:old.id;
  58.   end if;
  59. end TRI_test_user_AFR;
  60. --13.如果你想雙向同步,請在源數據庫中執行前6步,并在雙方都創建以下觸發器(當源數據庫表改變時,目的數據庫表跟著改變,目的數據庫表改變時,源數據庫表也改變)
  61. CREATE OR REPLACE TRIGGER BST114.TRI_TEST_USER_AFR
  62. AFTER DELETE OR INSERT OR UPDATE
  63. ON BST114.SN_TEST_USER 
  64. REFERENCING NEW AS NEW OLD AS OLD
  65. FOR EACH ROW
  66. declare
  67.     tmp_id number(10):=-1;
  68. begin
  69.   dbms_output.put_line(''begin'');
  70.   if inserting then
  71.       --select id into tmp_id from test_user where id=:new.id;    
  72.       for p in(select id from test_user where id=:new.id)
  73.       loop
  74.         tmp_id:=p.id;
  75.       end loop;
  76.       
  77.       dbms_output.put_line(tmp_id||''===------------'');
  78.       if (tmp_id=-1) then
  79.           insert into test_user(id,name,age)
  80.           values(:new.id,:new.name,:new.age);
  81.       end if;
  82.   end if;
  83.   
  84.   if updating then
  85.      dbms_output.put_line(''updated'');
  86.      for p in(select name,age from test_user where id=:old.id)
  87.      loop
  88.          if (p.name!=:new.name) or (p.age!=:new.age) then
  89.               update test_user set name=:new.name,age=:new.age where id=:old.id;
  90.          end if;
  91.      end loop;
  92.   end if;
  93.   
  94.   if deleting then
  95.       dbms_output.put_line(''deleted'');
  96.       delete from test_user where id=:old.id;
  97.   end if;
  98.   dbms_output.put_line(''end'');
  99. end TRI_test_user_AFR;
  100.  --為防止雙向同步觸發器死循環,所以要在觸發器中增加一些判斷,阻止死循環.
  101. --以上同步原理
  102. 1.首先創建一個dblink,可以訪問遠程數據庫
  103. 2.在本地創建一個快照,映射遠程數據表,當遠程數據表有變化時,會反應到快照中.
  104. 3.由于快照類似于視圖表,所以在本地為快照創建一個觸發器,當快照有變化時,會觸發相應事件.
  105. 4.在觸發器中寫同步數據的代碼.
  106. --附:快照刷新時間參數說明
  107. 一天的秒數=24小時*60分鐘*60鈔
  108. 所以要想在30秒后刷新,參數應該這樣寫 sysdate+30/(24*60*60)
  109. 1分鐘==sysdate+60/(24*60*60)
  110. 一天的分鐘數=24小時*60分鐘
  111. 一分鐘也可以這樣寫 sysdate+1/(24*60)
  112. 30分鐘==sysdate+30/(24*60)
  113. 60分鐘==sysdate+60/(24*60)
  114. 以此類推
  115. 1小時==sysdate+1/24==sysdate+60/(24*60)
  116. 1天==sysdate+1
  117. 一個月==sysdate+30
  118. 文章出處:http://www.diybl.com/course/7_databases/oracle/oraclejs/200855/113330.html

發表于 @ 2008年11月21日 13:07:00|評論(0 )|收藏

新一篇: DELPHI成批插入數據庫 | 舊一篇: 巧用dblink結合oracle快照實現兩臺服務器的數據同步