2011-09-22 125 views
1
CREATE OR REPLACE TRIGGER "DISC_CLIENT" 
BEFORE INSERT ON "PURCHASE" 
FOR EACH ROW 
DECLARE 
checkclient PURCHASE.CLIENTNO%TYPE; 
BEGIN 
SELECT Clientno INTO checkclient 
FROM PURCHASE 
GROUP BY ClientNo 
HAVING SUM(Amount)=(SELECT MAX(SUM(Amount)) FROM PURCHASE GROUP BY Clientno); 
IF :new.ClientNo = checkclient 
new.Amount := (:old.Amount * 0.90); 
END IF; 
END; 
/

似乎具有與此觸發的問題。我知道那裏我不能使用WHEN()子句的子查詢,所以我希望這會工作,但它不!想法任何人? :/Oracle觸發器子查詢問題

基本上我試圖讓這個觸發器在插入前對金額值應用折扣,如果客戶端匹配頂級客戶端的話! :)

+0

你試圖通過這個觸發器達到什麼目的?我想你想給在你店裏花費最多的客戶一個10%的價格折扣。但是這個觸發器不會這樣做 - 觸發器無法更改:新值和舊值以及:舊插入觸發器爲空。 –

回答

2

有這一輪非漂亮,但簡單的方法,創建一個視圖和更新。然後,您可以明確指出觸發器中的所有列並將它們放入表格中。創建一個1行2列表max_amount,然後在每次插入最大金額和clientno的情況下也會好得多。您應該在購買表中確實有折扣金額欄,因爲您應該知道您已給予折扣的用戶。收費金額爲amount - discount。這得益於兩個變異表,並且無法更新:new.amount以及使您的查詢更快,更快。就目前而言,如果當前交易最高,那麼實際上並不應用折扣,只有當客戶放置了以前的最高價時,我纔會這樣寫。

create or replace view purchase_view as 
    select * 
    from purchase; 

CREATE OR REPLACE TRIGGER TR_PURCHASE_INSERT 
    BEFORE INSERT ON PURCHASE_VIEW 
    FOR EACH ROW 

    DECLARE 

    checkclient max_amount.clientno%type; 
    checkamount max_amount.amount%type; 
    discount purchase.discount%type; 

    BEGIN 

    SELECT clientno, amount 
     INTO checkclient, checkamount 
     FROM max_amount; 

    IF :new.clientno = checkclient then 
     discount := 0.1 * :new.amount; 
    ELSIF :new.amount > checkamount then 
     update max_amount 
     set clientno = :new.clientno 
      , maxamount = :new.amount 
      ; 
    END IF; 

    -- Don-t specify columns so it breaks if you change 
    -- the table and not the trigger 
    insert into purchase 
    values (:new.clientno 
      , :new.amount 
      , discount 
      , :new.other_column); 
END TR_PURCHASE_INSERT; 
/
1

正如我所記得的,觸發器無法從表格中選擇觸發。 否則你會得到ORA-04091:表XXXX是變異的,觸發器/函數可能看不到它。 Tom advises我們不要把太多的邏輯放入觸發器中。

如果我理解你的查詢,就應該是這樣的:

SELECT Clientno INTO checkclient 
FROM PURCHASE 
GROUP BY ClientNo 
HAVING SUM(Amount)=(select max (sum_amount) from (SELECT SUM(Amount) as sum_amount FROM PURCHASE GROUP BY Clientno)); 

這樣,它會返回誰花的錢最多的客戶端。

但我覺得這是更好地做這種方式:

select ClientNo 
from (
    select ClientNo, sum (Amount) as sum_amount 
    from PURCHASE 
    group by ClientNo) 
order by sum_amount 
where rownum