我們使用視圖來抽象出我們的數據庫設計正在改變的事實......舊的,遺留代碼將所有用戶數據轉儲到一個非規格化表中;新設計在正常設計中將數據分開。出於多種原因(有些是合法的,有些是不合法的),我們的一些新開發必須針對新數據庫進行,因此用戶數據必須保持同步,直到新數據庫成爲用戶數據的權威來源。這是一個亂倫亂七八糟的事情,但這是我堅持的。由INSTEAD OF觸發器影響的更新()函數
我們選擇在視圖上使用替代觸發器來寫入兩個數據庫......唯一的另一種選擇是在權威源的表上寫入觸發器,但這可能會引入意外的副作用到現有的代碼中。
問題:如果我沒有在表中直接更新status_date,比如說,函數updating('status_date')
在視圖上的任何觸發器中都返回false。但是,instead-of觸發器必須在其更新查詢中包含status_date字段,因此它總是顯示爲已設置爲相同的值。
例如,我們在當前的用戶表狀態日期字段被觸發自動更新時,如果在更新中不包含用戶的狀態的改變它:
-- Don't change the status date if a date has been explicitly set
if (not updating('status_date')) then
:new.status_date := sysdate;
end if;
如果我直接作爲更新表:
update user_status set
status = 'GONE',
status_date = to_date('20170101','yyyymmdd')
where user_id = '123456';
該表將使用2017/01/01作爲日期。但是,保留日期會觸發它到sysdate。
-- The trigger will set status_date to sysdate
update user_status set
status = 'GONE'
where user_id = '123456';
在視圖扳機,我要更新的一切:
update user_status set
status = :new.status,
status_date = :new.status_date
where user_id = :new.user_id;
但是,這會導致updating('status_date')
總是在user_status表觸發回真正的 - 我要檢查的值,如果他們」重新相同,我必須假定日期沒有被設置。
-- Don't change the status date if a date has been explicitly set
if (:new.status_date = :old.status_date) then
:new.status_date := sysdate;
end if;
大多數情況下,它的工作原理是一樣的。除了我通過顯式設置保留當前日期而失去能力外 - 以下兩個查詢現在看起來相同,並且兩者都會更新狀態日期。然而,只有第二個應該:(
-- Not setting the date, trigger will use sysdate
update v_user_status set
status = 'GONE',
status_date = status_date
where user_id = '123456';
-- I'm correcting the status, but I need to keep the original date
update v_user_status set
status = 'GONE'
where user_id = '123456';
我怎樣才能保持一個字段的「不更新」的狀態從視圖觸發更新表時?
我有點困惑。通過表觸發器中的「不更新」檢查,兩個視圖更新都將日期設置爲今天。平等檢查既不更新它。但基本上你只是想要更新視圖,就像直接更新表一樣工作,無論你設置狀態日期爲自己(保持不變),設置爲特定日期還是不設置(因此它會SYSDATE)? –