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

火曜日までにこれを機能させるのを手伝ったほうがいいよね。(サンタさん、あなたですか???)

詳細をすべてのギフトのリストからギフトの数に変更するだけで、クエリと保存が簡単になります。次のように、トリガーで 3 つのクエリを使用して、ドナーから贈られたギフトの数、レシーバーが受け取ったギフトの数、およびペアによって交換されたギフトの数をクエリできます (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;
/

テーブルが巨大になった場合は、1 つのクエリで解決できます。

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 に答える