我必须在插入时为一个表编写一个触发器,该触发器将根据“捐赠者”是否已经做出了“保证”来自动设置表中某一列的值。我试过几种不同的方法,我能做的最好的就是一个触发器导致直接递归,另外三个触发器都导致表错误的变异。我现在所做的一切似乎只会让事情变得更糟,而且找不到解决办法。有人请帮忙。
表格:
CREATE TABLE DD_Pledge (
idPledge number(5),
idDonor number(4),
Pledgedate DATE,
Pledgeamt number(8,2),
idProj number(5),
idStatus number(2),
Writeoff number(8,2),
paymonths number(3),
Campaign number(4),
Firstpledge char(1),
CONSTRAINT pledge_id_pk PRIMARY KEY(idPledge),
CONSTRAINT pledge_idDonor_fk FOREIGN KEY (idDonor) REFERENCES dd_donor (idDonor),
CONSTRAINT pledge_idProj_fk FOREIGN KEY (idProj) REFERENCES dd_project (idProj),
CONSTRAINT pledge_idStatus_fk FOREIGN KEY (idStatus) REFERENCES dd_status (idStatus));
递归触发器:
CREATE OR REPLACE TRIGGER firstpledge_tr
BEFORE INSERT ON dd_pledge
FOR EACH ROW
DECLARE
tr_firstpledge dd_pledge.firstpledge%TYPE;
iddonor_count INTEGER;
BEGIN
SELECT COUNT(iddonor) INTO iddonor_count FROM dd_pledge WHERE iddonor = :NEW.iddonor;
IF iddonor_count > 0 THEN
tr_firstpledge := 'N';
ELSE
tr_firstpledge := 'Y';
END IF;
INSERT INTO dd_pledge(idpledge,iddonor,pledgedate,pledgeamt,idproj,idstatus,writeoff,paymonths,campaign,firstpledge)
VALUES (:NEW.idpledge,:NEW.iddonor,:NEW.pledgedate,:NEW.pledgeamt,:NEW.idproj,:NEW.idstatus,:NEW.writeoff,:NEW.paymonths,:NEW.campaign,tr_firstpledge);
-- COMMIT;
END;
突变触发1:
CREATE OR REPLACE TRIGGER firstpledge_tr
AFTER INSERT ON dd_pledge
FOR EACH ROW
DECLARE
tr_firstpledge dd_pledge.firstpledge%TYPE;
iddonor_count INTEGER;
BEGIN
SELECT COUNT(iddonor) INTO iddonor_count FROM dd_pledge WHERE iddonor = :NEW.iddonor;
UPDATE dd_pledge
SET firstpledge = CASE WHEN iddonor_count<1 THEN 'N' ELSE 'Y' END
WHERE idpledge = :NEW.idpledge;
END;
2条答案
按热度按时间z8dt9xmd1#
实际的插入操作无论如何都会发生。只需设置新值:
wko9yo5t2#
任何时候,只要你设法让自己得到一个变异表错误,你就有一个设计缺陷(也请参阅ask tom,旧的,但仍然有效)。在这种情况下,您不应该使用触发器,而是在发出insert语句之前,在业务逻辑层中确定并设置tru firstassempt。但是如果你坚持使用触发器,那么你需要一个复合触发器。这避免了错误,但在多用户环境中仍可能带来麻烦。
这完全避免了在每一行处理过程中实际访问表(这是导致变异表错误的原因)。通常情况下,你可以选择逃脱-但这里的情况下,没有。看这里的小提琴。
它的功能:
声明部分:设置并初始化一个集合,以保存后续的idprovider值。它创建了一对常数。
before行部分:保存上述集合中的当前idconsor。它还设定了“n”的第一个承诺,假设随着时间的推移,你会有更多的重复捐赠者而不是新的捐赠者。
最后,after statement部分:对于已保存但没有事先质押的idprovider值,将首次质押撤销为“y”。