0

我有一张 Giving(donor, receiver, giftname) 表格,列出了谁给谁送了礼物。我正在尝试编写一个触发器,如果​​它是捐赠者赠送的第一份礼物,接收者收到的第一份礼物,或者它是捐赠者和接收者的第一份礼物,它将触发。基本上我需要做的是将新捐赠者的名字与所有捐赠者的名单进行比较,并确保它还没有。然后对接收器执行相同的操作。这是我的尝试,但我确信这是不对的,因为我的变量 existingreceivers 和 existingdonors 不会做我想让他们做的事情。这些变量existingreceivers 和existingdonors 是否会存储多个值?如果没有,我该如何完成我需要做的事情?

create or replace TRIGGER FirstGift
BEFORE INSERT OR UPDATE OF donor,receiver ON GIVING
FOR EACH ROW
DECLARE
ExistingReceivers varchar(255);
ExistingDonors varchar(255);

BEGIN
select donor into existingdonors
from giving;

select receiver into existingreceivers
from giving;

--first gift for donor, first gift for receiver
if(:new.donor not in existingdonors and :new.receiver not in existingreceivers)then
dbms_output.put_line('This is the first gift received by ', :new.receiver, 'and the first given by ', :new.donor);
insert into messages (intid, donor, receiver, giftname, msg) values (test_seq.nextval, :new.donor, :new.receiver, :new.giftname, 'First Gift Given and First Received!');


--first gift for donor, not first gift for receiver
elsif(:new.donor not in existingdonors)then
dbms_output.put_line('This is the first gift given by ', :new.donor);
insert into messages (intid, donor, receiver, giftname, msg) values (test_seq.nextval, :new.donor, :new.receiver, :new.giftname, 'First Gift Given!');

--first gift for receiver, not first gift for donor
elsif(:new.receiver not in existingreceivers)then
dbms_output.put_line('This is the first gift received by ', :new.receiver);
insert into messages (intid, donor, receiver, giftname, msg) values (test_seq.nextval, :new.donor, :new.receiver, :new.giftname, 'First Gift Received!');

end if;

end;
4

1 回答 1

2

我们最好帮助您在星期二之前完成这项工作,不是吗。(是你吗,圣诞老人???)

您的方法应该可以正常工作,只需将详细信息从所有礼物的列表更改为礼物的数量,这样更易​​于查询和存储。您可以使用触发器中的三个查询来查询捐赠者赠送的礼物数量、接收者收到的礼物数量以及两人交换的礼物数量,如下所示(我省略了 INSERT INTO MESSAGES 位):

CREATE OR REPLACE TRIGGER FirstGift
  BEFORE INSERT OR UPDATE OF donor, receiver ON GIVING FOR EACH ROW
DECLARE
  num_donor     NUMBER;
  num_receiver  NUMBER;
  num_both      NUMBER;
BEGIN
  SELECT count(*) INTO num_both
    FROM giving
   WHERE donor = :new.donor AND receiver = :new.receiver;

  SELECT count(*) INTO num_donor
    FROM giving
   WHERE donor = :new.donor;       

  SELECT count(*) INTO num_receiver
    FROM giving
   WHERE donor = :new.donor;  

  IF num_both = 0 THEN 
    dbms_output.put_line(:new.donor||' and '||:new.receiver);
  ELSE 
    IF num_donor = 0 THEN
      dbms_output.put_line(:new.donor);
    END IF;

    IF num_receiver = 0 THEN
      dbms_output.put_line(:new.receiver);
    END IF;
END;
/

如果表变得很大,你可以用一个查询来解决它:

CREATE OR REPLACE TRIGGER FastFirstGift
  BEFORE INSERT OR UPDATE OF donor, receiver ON GIVING FOR EACH ROW
DECLARE
  num_donor     NUMBER;
  num_receiver  NUMBER;
  num_both      NUMBER;
BEGIN
  SELECT SUM(CASE WHEN donor    = :new.donor    THEN 1 END),
         SUM(CASE WHEN receiver = :new.receiver THEN 1 END),
         SUM(CASE WHEN donor    = :new.donor
                   AND receiver = :new.receiver THEN 1 END)
    INTO num_donor, num_receiver, num_both
  FROM giving;

  IF num_both = 0 THEN 
    dbms_output.put_line(:new.donor||' and '||:new.receiver);
  ELSE 
    IF num_donor = 0 THEN
      dbms_output.put_line(:new.donor);
    END IF;

    IF num_receiver = 0 THEN
      dbms_output.put_line(:new.receiver);
    END IF;
  END IF;
END;
/

希望这能回答你的问题...

于 2012-12-21T21:27:52.003 回答