Decode360's Blog

          業(yè)精于勤而荒于嬉 QQ:150355677 MSN:decode360@hotmail.com

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 ::  :: 管理 ::
            397 隨筆 :: 33 文章 :: 29 評論 :: 0 Trackbacks
          用Trigger為MView手動增加時間戳
          ?
          ?
          ??? 很多人都遇到過這樣的問題:源數(shù)據(jù)庫里的表沒有時間戳,或者有時間戳的字段但沒有嚴格執(zhí)行,而歷史數(shù)據(jù)又可能會經(jīng)常性得被修改。這對于ETL數(shù)據(jù)抽取來說將是一個很大的問題,特別是對于不能動源庫的情況下,很難解決這個問題。最近又因為這個問題,考慮了很久,最后打算在MView同步數(shù)據(jù)的基礎(chǔ)上,通過Trigger來手動增加時間戳。
          ?
          ??? 考慮對MView操作的原因是因為現(xiàn)有的數(shù)據(jù)同步就是用MView做的,據(jù)說用Stream同步數(shù)據(jù)也可以用類似的辦法添加時間戳的,這個相關(guān)的問題以后再研究,講一下MView下的操作。
          ?
          ??? 首先MView有一些天然的限制,因為最初我考慮的是在建MView的時候就添加一個SYSDATE的字段,這樣每次同步就會自動將同步時的sysdate也加入到新的物化視圖中,但是這個嘗試失敗了,因為增量(Fast)更新不支持復雜表結(jié)構(gòu),而Oracle認為新增字段的表都屬于復雜表,會報錯如下:
          ??? ORA-12015: cannot create a fast refresh materialized view from a complex query
          ??? 然后又希望能夠通過物化視圖的on commit刷新模式對表進行刷新,這樣可以直接查詢ora_rowscn來判斷某行的更新時間,但是很遺憾,on commit的刷新模式只針對同庫下的更新,不支持遠程同步,所以沒辦法只能用Trigger來自己手工增加時間戳。具體的實驗步驟如下:
          ?
          ?
          ?
          1、在源庫中建立表t1,并添加mv log:
          ?
          SQL> create table t1(a int primary key,b int);
          ?
          Table created.
          ?
          SQL> insert into t1 values(1,2);
          ?
          1 row created.
          ?
          SQL> insert into t1 values(3,4);
          ?
          1 row created.
          ?
          SQL> commit;
          ?
          Commit complete.
          ?
          SQL> select * from t1;
          ?
          ???????? A????????? B
          ---------- ----------
          ???????? 1????????? 2
          ???????? 3????????? 4
          ?
          SQL> create materialized view log on t1 with primary key;
          ?
          Materialized view log created.
          ?
          ?
          2、在新 庫上添加源庫的DB LINK:
          ?
          SQL> create database link wxq_db
          ? 2? connect to wangxiaoqi identified by wangxiaoqi
          ? 3? using '(DESCRIPTION =
          ? 4????? (ADDRESS_LIST =
          ? 5??????? (ADDRESS = (PROTOCOL = TCP)(HOST = 10.20.1.127)(PORT = 1521))
          ? 6????? )
          ? 7????? (CONNECT_DATA =
          ? 8??????? (SERVICE_NAME = devWXQowb)
          ? 9?????? )
          10????? )';

          Database link created.
          ?
          SQL> select * from t1@wxq_db ;
          ?
          ???????????? A????????????? B
          -------------- --------------
          ???????????? 1????????????? 2
          ???????????? 3????????????? 4
          ?
          ?
          3、在新庫創(chuàng)建物化視圖,設置增量刷新
          ?
          SQL> create materialized view wxq_t1
          ? 2? build deferred
          ? 3? refresh fast
          ? 4? on demand
          ? 5? with primary key
          ? 6? as
          ? 7? select * from
          t1@wxq_db ;

          Materialized view created.
          ?
          SQL> select * from wxq_t1;
          ?
          no rows selected
          ?
          --第一次必須要全量刷新
          ?
          SQL> exec dbms_mview.refresh('wxq_t1','complete');
          ?
          PL/SQL procedure successfully completed.
          ?
          SQL> select * from wxq_t1;
          ?
          ???????? A????????? B
          ---------- ----------
          ???????? 1????????? 2
          ???????? 3????????? 4
          ?
          ?
          4、在新庫創(chuàng)建關(guān)于表T1的Trigger:
          ?
          SQL> create table t1_log(a int,c_flag varchar2(2),modifydate date);
          ?
          Table created.
          SQL> create or replace trigger t1_tgr after update or insert or delete on wxq_t1
          ? 2???? referencing old as oldrow new as newrow for each row
          ? 3? begin
          ? 4???? if inserting then
          ? 5???? insert into t1_log values(:newrow.a,'I',sysdate);
          ? 6???? end if;
          ? 7???? if updating then
          ? 8???? insert into t1_log values(:oldrow.a,'U',sysdate);
          ? 9???? end if;
          10???? if deleting then
          11???? insert into t1_log values(:oldrow.a,'D',sysdate);
          12???? end if;
          13? end;
          14? /

          Trigger created.
          ?
          ?
          5、來測試一下在源庫中進行插入、刪除、修改操作
          ?
          SQL> select * from t1;
          ?
          ???????? A????????? B
          ---------- ----------
          ???????? 1????????? 2
          ???????? 3????????? 4
          ?
          SQL> insert into t1 values(10,20);
          ?
          1 row created.
          ?
          SQL> update t1 set b=40 where a=3;
          ?
          1 row updated.

          SQL> delete from t1 where a=1;
          ?
          1 row deleted.
          SQL> commit;
          ?
          Commit complete.
          ?
          SQL> select * from t1;
          ?
          ???????? A????????? B
          ---------- ----------
          ??????? 10???????? 20
          ???????? 3???????? 40
          ?
          SQL> column change_vector$$ format a20
          SQL> select * from mlog$_t1;
          ?
          ???????? A SNAPTIME$$ DM OL CHANGE_VECTOR$$
          ---------- ---------- -- -- --------------------
          ??????? 10 4000-01-01 I? N? FE
          ???????? 3 4000-01-01 U? U? 04
          ???????? 1 4000-01-01 D? O? 00
          ?
          ?
          --然后在新庫中查看時候生效
          ?
          SQL> select * from t1_log;
          ?
          no rows selected
          ?
          SQL> exec dbms_mview.refresh('wxq_t1','fast');
          ?
          PL/SQL procedure successfully completed.
          ?
          SQL> select * from t1_log;
          ?
          ???????? A C_ MODIFYDATE
          ---------- -- ----------
          ???????? 1 D? 2009-06-18
          ??????? 10 I? 2009-06-18
          ???????? 3 U? 2009-06-18
          ?
          ?
          6、創(chuàng)建最終視圖,方便實際操作:
          ?
          SQL> create or replace view t1 as
          ? 2??? select wxq_t1.a,wxq_t1.b,t1_log.c_flag,t1_log.modifydate
          ? 3????? from wxq_t1,t1_log
          ? 4???? where wxq_t1.a = t1_log.a
          ? 5?????? and t1_log.c_flag in ('I','U')
          ? 6??? union all
          ? 7??? select t1_log.a,wxq_t1.b,t1_log.c_flag,t1_log.modifydate
          ? 8????? from wxq_t1,t1_log
          ? 9???? where t1_log.a = wxq_t1.a(+)
          10?????? and t1_log.c_flag = 'D';
          ?
          View created.
          ?
          SQL> select * from t1;
          ?
          ???????? A????????? B C_ MODIFYDATE
          ---------- ---------- -- ----------
          ??????? 10???????? 20 I? 2009-06-18
          ???????? 3???????? 40 U? 2009-06-18
          ???????? 1??????????? D? 2009-06-18
          ?
          ?
          ??? 這樣就創(chuàng)建完成了,不但為新記錄添加了時間戳,而且也增加了被刪除記錄的時間(被刪除記錄只剩下主鍵和時間字段信息)。不過這個方法有些過于繁瑣,只能在對少數(shù)表加時間戳的情況下使用,而不能全庫操作,而且針對每一個表都需要建一個trigger,效率也是個問題。但是好處是創(chuàng)建之后對于前臺查詢時完全透明的,注意最終的查詢view名稱是與源庫的表名一致的,這樣的封裝性對前臺操作的感覺非常好。
          ?
          ?
          ?
          ?
          posted on 2009-06-18 21:54 decode360 閱讀(453) 評論(0)  編輯  收藏 所屬分類: 10.DB_Tools
          主站蜘蛛池模板: 徐州市| 二手房| 元江| 双城市| 临猗县| 青海省| 繁昌县| 施秉县| 鸡西市| 兴国县| 花垣县| 太谷县| 安庆市| 彰武县| 阿鲁科尔沁旗| 定远县| 西乌珠穆沁旗| 郎溪县| 苏尼特左旗| 郸城县| 玛沁县| 清镇市| 漳州市| 博乐市| 哈巴河县| 潮州市| 永安市| 佛坪县| 荔浦县| 朔州市| 浦县| 高雄县| 和龙市| 岗巴县| 佛学| 张家港市| 沾化县| 沙洋县| 五华县| 荣昌县| 金阳县|