我怎么能修复我的触发器自动确定是否第一次捐赠和更新单列



我在尝试为我的表创建触发器时遇到了瓶颈。我有一个捐赠表,其中有一个列(first_donation),它被选中为"Y"或"N",这取决于它是否是捐赠者的第一次捐赠。我想通过一个触发器自动添加"Y"或"N"来实现这个过程的自动化,如果添加了新的捐赠。所以,如果一个捐赠者提交了一个新的捐赠,或者这是他们的第一次捐赠,列(first_donation)将被调整为反映Y或n。我第一次尝试触发器,一开始似乎并不太令人生畏,语言似乎比我上一本关于Java Script的书更容易。如有任何指导,不胜感激。

   CREATE OR REPLACE TRIGGER FIRST_DONATION_TG
      AFTER 
      INSERT OF donation_id  --id of donation pledge
      ON tt_donate
      FOR EACH ROW   
   BEGIN
      IF INSERTING THEN
      UPDATE tt_donation
      SET first_donation := 'Y';
      ELSE 
      SET first_donation := 'N';
   END IF;
   END FIRST_DONATION_TG;

下面你会发现一个工作的例子,它应该做你正在寻找的。我不解释基本触发器语法的细节,因为您可以从精美的手册中阅读:PL/SQL触发器。

before insert触发器允许您在将行插入表之前修改插入的值(注意使用:new伪记录来访问要插入的行)。所以在这里,我们将查看捐赠者是否进行了捐赠,然后调整标志值。注意,此时表中还没有我们要插入的行。

还请注意保护数据的示例表约束始终具有有效值。

<<p> 示例表/strong>
create table donation (
 donator_id number not null
,amount number not null check(amount > 0)
,first_ varchar2(1) not null check(first_ in ('Y', 'N'))
,date_ date default sysdate not null
);
-- ensure searching donators is effective
create index donation_idx1 on donation(donator_id);

create or replace trigger donation_trg1
before insert on donation
for each row
declare
  v_first_exists number;
begin
  -- check if a donator has made a donation
  select count(*) into v_first_exists
  from donation
  where donator_id = :new.donator_id
  -- we're only interested if a donation exists therefore
  -- we don't need to count beyond 1
  and rownum = 1;
  -- adjust the value before database inserts the row
  :new.first_ :=
    case
      when v_first_exists = 0 then 'Y'
      else 'N'
    end;
end;
/

运行示例

insert into donation(donator_id, amount) values(1, 10);
insert into donation(donator_id, amount) values(1, 20);
insert into donation(donator_id, amount) values(1, 30);
insert into donation(donator_id, amount) values(2, 10);
insert into donation(donator_id, amount) values(2, 20);
insert into donation(donator_id, amount) values(2, 30);
select * from donation;
DONATOR_ID     AMOUNT FIRST_ DATE_
---------- ---------- ------ -------------------
         1         10 Y      2015-07-22 09:20.10
         1         20 N      2015-07-22 09:20.10
         1         30 N      2015-07-22 09:20.10
         2         10 Y      2015-07-22 09:20.10
         2         20 N      2015-07-22 09:20.10
         2         30 N      2015-07-22 09:20.10
 6 rows selected

除非这是家庭作业,否则我强烈建议不要将这样的数据作为表数据的一部分。也就是说,每行都有一个指示符,表示该行与其他行之间的关系。

如果错过了"第一次捐赠"条目,直到输入了几次后续捐赠后才输入该怎么办?

如果"第一次捐赠"条目输入错误-日期错误,更正后的日期现在将其放在一次或多次捐赠之后怎么办?或者相反,更正后的捐赠日期现在排在第一位?

这里有很多"假设",每个假设都说明了数据是如何变坏的,导致你不得不分析和纠正现在的坏数据——也就是说,有人,可能是客户,生成报告抱怨数据不正确。

不太容易受底层数据变化影响的方法是一两个视图。一个视图将只显示每个捐赠者的第一次捐赠。这可能会满足你的应用程序中只关注第一次捐赠的任何部分。

另一个视图可以是对每个捐赠者进行分区,生成行号(按捐赠日期排序)。第一笔捐款是每组的第一行。case语句可以根据需要生成'Y'和'N'。

现在,不需要复杂的触发器,无论如何操作底层数据,改变捐赠的顺序,下一个查询将生成正确的结果。

你的工作变得非常容易你保证正确的结果根据数据的当前状态。你还能要求什么呢?

相关内容

最新更新