【问题标题】:Oracle - Using a trigger to delete a rowOracle - 使用触发器删除一行
【发布时间】:2018-04-19 20:47:07
【问题描述】:

当对Condo_assign 进行插入时,我使用多个触发器将条目添加到reserveError 表以指示错误是什么。在他们登录reserveError 后,我现在尝试使用另一个触发器从condo_assign 中删除导致问题的记录。基本上,错误的插入应该记录在 ReserveError 中并从 Condo_assign 中删除。问题是,虽然我的删除触发器编译并没有导致任何问题,但它似乎没有做任何事情。当我select * from condo_assign 时,错误的条目仍然存在。

Condo_Assign 表:

CREATE TABLE Condo_Assign (
  MID INT
, RID VARCHAR2(3)
, CONSTRAINT Condo_Assign Primary Key (MID,RID)
, CONSTRAINT MID_Assign_FK Foreign Key (MID) references SkiClub (MID)
, CONSTRAINT RID_Assign_FK Foreign Key (RID) references Condo_Reservation (RID)
);

reserveError 表:

CREATE TABLE ReserveError (
Err INT PRIMARY KEY
, MID INT
, RID VARCHAR2(3)
, errorDate DATE
, errorCode VARCHAR2(6)
, errorMsg VARCHAR2(60)
, CONSTRAINT Error_MID_FK FOREIGN KEY (MID) REFERENCES SkiClub
, CONSTRAINT Error_RID_FK FOREIGN KEY (RID) REFERENCES Condo_Reservation
);

触发触发器的过程:

CREATE OR REPLACE Procedure addCondo_Assign
(
inMID in Condo_Assign.MID%type
, inRID in Condo_Assign.RID%type
, inPaymentDate in Payment.PaymentDate%type
, inPayment in Payment.Payment%type
)
is
begin
insert into Condo_Assign (MID,RID) values (inMid,inRid);
IF inPayment >= 50 then 
    insert into Payment (MID,RID,PaymentDate,Payment) values (inMID,inRID,inPaymentDate,inPayment);
ELSE
    raise_application_error(-20088,'Deposit less than 50');
end if;

exception
    when others then
    raise_application_error(-20005,'Cannot add to entry to Condo_Assign Table.');
end addCondo_Assign;
/

写入 ReserveError 表的触发器

-- Trigger to prevent gender mismatchs in room assignment
CREATE OR REPLACE TRIGGER Gender_Assign_Trigger
BEFORE INSERT ON Condo_Assign
FOR EACH ROW
DECLARE
Room_Gender Char(1);
Guest_Gender Char(1);
BEGIN
SELECT Gender 
    INTO Room_Gender
    From Condo_Reservation
    WHERE RID = :new.RID;
SELECT Gender
    INTO Guest_Gender
    FROM SkiClub
    WHERE MID = :new.MID;       
IF Room_Gender = 'M' AND Guest_Gender = 'F' THEN
    addReserveError(:new.MID,:new.RID,SYSDATE,'g00001','Female guest assigned to male room');
ELSIF Room_Gender = 'F' AND Guest_Gender = 'M' THEN
    addReserveError(:new.MID,:new.RID,SYSDATE,'g00002','Male guest assigned to female room');
END IF;
END Gender_Assign_Trigger;
/

应该从 condo_assign 中删除条目的触发器:

CREATE OR REPLACE TRIGGER Remove_errors_trigger
after Insert on ReserveError
FOR EACH ROW
BEGIN
  DELETE FROM Condo_Assign
  WHERE MID = :new.MID and RID = :new.RID;
END remove_errors_trigger;
/

【问题讨论】:

    标签: sql oracle plsql database-trigger


    【解决方案1】:

    整个过程在插入前触发器中开始。

    尝试删除记录的代码不会删除任何内容,因为该记录尚未插入。在触发删除代码时没有要删除的内容。

    通常签入触发器可防止插入不正确的数据并引发异常。插入数据的代码必须处理异常。

    但是您已经有一个处理插入的过程。它甚至对存款进行检查。为什么不在那里处理性别检查?

    【讨论】:

    • 这是绝对正确的——你有一个 PL/SQL 层来管理这个事务。您应该将任何业务逻辑放在这一层。如果所有的逻辑都放在一个地方,那么其他人就很容易找到和理解。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-02
    相关资源
    最近更新 更多