2011-09-22 149 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