一種選擇是創建一個由觸發器填充上user_product
一個user_product_history
表,然後定義轉換舊「刪除」排在歷史表爲update
,如果該行被隨後插入的觸發器。
CREATE TABLE user_product_history (
user_id number,
product_id number,
cost number,
operation_type varchar2(1),
operation_date date
);
CREATE TRIGGER trg_user_product_history
AFTER INSERT OR UPDATE OR DELETE ON user_product
FOR EACH ROW
DECLARE
l_cnt integer;
BEGIN
IF(deleting)
THEN
insert into user_product_history(user_id, product_id, cost, operation_type, operation_date)
values(:old.user_id, :old.product_id, :old.cost, 'D', sysdate);
ELSIF(updating)
THEN
insert into user_product_history(user_id, product_id, cost, operation_type, operation_date)
values(:new.user_id, :new.product_id, :new.cost, 'U', sysdate);
ELSIF(inserting)
THEN
select count(*)
into l_cnt
from user_product_history
where operation_type = 'D'
and user_id = :new.user_id
and product_id = :new.product_id;
if(l_cnt > 0)
then
update user_product_history
set operation_type = 'U',
operation_date = sysdate,
cost = :new.cost
where operation_type = 'D'
and user_id = :new.user_id
and product_id = :new.product_id;
else
insert into user_product_history(user_id, product_id, cost, operation_type, operation_date)
values(:new.user_id, :new.product_id, :new.cost, 'I', sysdate);
end if;
END IF;
END;
從效率的角度來看,然而,這樣的刪除和插入,而不是更新將意味着,你將遠遠更多的負載您的數據庫比是必要的。你會做比實際需要更多的I/O。最終你會得到更復雜的代碼來處理更改。你幾乎肯定會更好地弄清楚已經發生了什麼變化,然後只是更新這些行。
爲什麼不只是做一個更新而不是刪除和插入? – 2012-04-10 03:57:51
@丹A.它基本上是從用戶到產品的一對多關係。用戶可以有100多種產品。如果用戶現在有10個產品。他以後可能會有40種產品。如果我向用戶添加新產品,我將不得不檢查該用戶產品映射是否存在於表中。如果是,則更新,如果沒有,則插入。所以對我來說,很容易刪除一切,然後再插入所有產品。這樣我不必檢查現有的和新的記錄,並相應地運行插入或更新查詢。 – ashishjmeshram 2012-04-10 04:05:32
當您嘗試追蹤歷史記錄時,您無法檢查是否存在要更新的產品會帶來任何便利。在我看來,最好通過實際進行「技術更新」來執行「邏輯更新」。如果您決定在產品記錄中添加「create_date」和「last_updated」列,該怎麼辦?如果您更新現有記錄,這樣做很簡單。 – 2012-04-10 14:03:37