像我們使用 oracle, 如果要將一個 Table 的資料自 A DB 複製到 B DB, 當然有很多做法, 像使用 MView 就是一個極為簡單的解決方案, 但如果是多個要複製到一個, 例如 A, C DB 複製到 B DB, 又不想因為 A DB 有問題中斷服務, 導致 C DB 的資料沒有複製到 B DB. 目前想到的就是自己使用 Trigger 做 Replication 的行為.
舉一個最簡單的例子, 假設要處理一個產品定義的 Prod Table, Schema 如下, 我們將對這一個 table 所做的 DML 都記錄起來, 然後再將這些 DML 拿到目的 DB 去執行就可以達成我們的目的.
--要複製資料的 table, PK {prod_id}
CREATE TABLE Prod
(prod_id VARCHAR2(64),
descr VARCHAR2(128),
price NUMBER(10,0))
/
-- Triggers
CREATE OR REPLACE TRIGGER prod_dmllogger
AFTER
INSERT OR DELETE OR UPDATE
ON prod
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
DECLARE
BEGIN
IF INSERTING THEN
INSERT INTO prod_DMLLog(sn,dml_sql)
VALUES (prod_SN.NEXTVAL, 'INSERT INTO prod (prod_id,descr,price) VALUES (' || '''' || :NEW.prod_id || ''',' || '''' || :NEW.descr || ''',' || NEW.price ||')');
ELSIF UPDATING THEN
INSERT INTO prod_DMLLog(sn,dml_sql)
VALUES (prod_SN.NEXTVAL, 'UPDATE prod SET ' || 'descr=''' || :NEW.descr || ''',' || 'price=' || :NEW.price || ' WHERE ' || 'prod_id=''' || :OLD.prod_id || '''');
ELSIF DELETING THEN
INSERT INTO prod_DMLLog(sn,dml_sql) VALUES (prod_SN.NEXTVAL, 'DELETE FROM prod WHERE ' || 'prod_id=''' || :OLD.prod_id || '''');
END IF;
END;
/
--紀錄所有 DML table
CREATE TABLE prod_DMLLog
(sn NUMBER(25,0) NOT NULL,
dml_sql CLOB NOT NULL))
/