我創建了2個表格:INFORMATION
和FEED
。如何讓列的值自動反映,當值插入/更新/刪除/從同一個表中的另一列?
INFORMATION has 2 attributes : ID(Primary Key), TOT_AMOUNT.
FEED has 4 attributes : ID(Foreign key refer INFORMATION(ID)), S_AMOUNT, S_DATE, TOT_REM.
現在,我要插入/更新/從TOT_REM
刪除值/的基礎上,S_AMOUNT
和TOT_AMOUNT
的插入/刪除/更新。
樣本內容是:
INFORMATION Table
------------------
ID | TOT_AMOUNT
1 | 100
2 | 20
3 | 50
...
FEED Table
----------------------------------------
ID | S_AMOUNT | S_DATE | TOT_REM
1 | 10 |10.10.2010| 90
1 | 10 |13.10.2010| 80
1 | 30 |17.10.2013| 50
1 | 10 |20.10.2016| 40
...
我們需要自動插入值到TOT_REM
屬性的基礎上,更新/插入/上S_AMOUNT
進行操作刪除,與TOT_AMOUNT
& S_AMOUNT
幫助。
在任何時候,TOT_REM不能小於0。而且,TOT_REM需要自動插入/刪除/更新,使得
TOT_REM for i(at a specific date) = (TOT_AMOUNT for ID=i) -
SUM(S_AMOUNT of all instances of ID=i,
which is later than the S_DATE for ID=i);
因此,假設如果我們刪除第二元組(1, 10,'13 .10.2010' ,80),的BR_FEED
反射狀態應該是:
FEED Table
----------------------------------------
ID | S_AMOUNT | S_DATE | TOT_REM
1 | 10 |10.10.2010| 90
1 | 30 |17.10.2013| 60
1 | 10 |20.10.2016| 50
...
我寫了一個觸發器,其失敗表示
ORA-04091: table SSUMAN.FEED is mutating, trigger/function may not see it
代碼觸發是:
CREATE OR REPLACE TRIGGER BR_INSERT_TRB
AFTER DELETE OR INSERT OR UPDATE OF S_AMOUNT ON FEED
FOR EACH ROW
BEGIN
IF DELETING THEN
UPDATE FEED bf
SET bf.TOT_REM = bf.S_AMOUNT + :OLD.S_AMOUNT;
END IF;
IF INSERTING THEN
INSERT INTO FEED (TOT_REM) VALUES(
((SELECT TOT_AMOUNT FROM INFORMATION bi WHERE bi.ID=:NEW.ID) -
(SELECT SUM(S_AMOUNT) FROM FEED bf where bf.ID=:NEW.ID) -
:NEW.S_AMOUNT);
END IF;
IF UPDATING THEN
UPDATE FEED bf
SET bf.TOT_REM = (SELECT TOT_AMOUNT FROM BR_INFORMATION bi WHERE bi.ID=bf.ID) -
(SELECT SUM(S_AMOUNT) FROM FEED bf where bf.ID=:NEW.ID) -
:NEW.S_AMOUNT
WHERE :NEW.ID IS NOT NULL;
END IF;
END;
問題:
- 是這種做法有缺陷?我可以通過這種方式達到我想要的效果嗎?[可選]
- 是否有任何將視圖帶到這裏的範圍?我無法想象那一行!也許,缺乏經驗...... [可選]
- 任何更好的方法,讓TOT_REM值可以自動反映?[強制來回答]
當你說「TOT_REM不能比0少」 - 你的意思是,作爲計算TOT_REM邏輯的一部分,還是應該有問題的插入/更新/刪除被拒絕,因爲它會導致TOT_REM變得消極?這兩者完全不同,並以不同的方式解決。 – mathguy
@mathguy - 應該拒絕,謝謝澄清。任何其他細節需要? –
我在這裏看到一些困難。最大的是開始時對TOT_REM的計算。如果刪除10.10.2010行,則以下行中的TOT_REM需要從INFORMATION表中讀取,而不是從其上面的行中讀取。如果您在第一個(2010年10月10日之前)之上添加一行,則10.10.2010 TOT_ROM將需要根據上面的行進行計算,而不是從INFORMATION中計算。更大的問題仍然是:你拒絕一行,因爲它會使TOT_ROM成爲負面。稍後,您會刪除一個包含更舊日期的行......現在您需要先將您拒絕的行取回嗎? – mathguy