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()子句,所以我希望这可以工作,但它不会!想法有人吗? :/
如果客户端与顶级客户端匹配,基本上我试图让这个触发器在插入之前对金额值应用折扣! :)
答案 0 :(得分: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 :(得分:1)
我记得一个触发器无法从表中选择它被触发。 否则你会得到ORA-04091:表XXXX正在变异,触发/功能可能看不到它。汤姆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