PL/SQL - 触发器仅在前一个触发器成功时调用
PL/SQL - Trigger only to be called on success of previous trigger
在我正在创建的数据库中,我有两个触发器,它们都在 table Child
.
上的 BEFORE INSERT
上触发
第一个触发器检查尝试插入的 Child_Birthday
值是否最多为今天;因此,如果值为明天,触发器将引发用户定义的异常。
第二个触发器在第一个触发器之后触发,这将为插入的记录创建自定义 ID 值。
但是,在测试触发器时,我插入了明天的日期,即 15-JAN-15
,该行仍然插入到 table。我假设这是因为第二个触发器仍然触发并插入记录,而不管第一个触发器引发异常(如果我在这里错了请纠正我)。
我想要的是第二个触发器仅在第一个触发器未引发异常时触发。
第一个触发器:
create or replace TRIGGER BirthdayCheck
BEFORE INSERT ON Child
FOR EACH ROW
DECLARE
dateError EXCEPTION;
BEGIN
IF :NEW.Child_Birthday > SYSDATE
THEN
RAISE dateError;
END IF;
EXCEPTION
WHEN dateError
THEN
DBMS_OUTPUT.PUT_LINE('ERROR: YOU HAVE ATTEMPTED TO INSERT A FUTURE DATE');
END;
第二个触发器:
create or replace TRIGGER ChildID
BEFORE INSERT ON Child
FOR EACH ROW
FOLLOWS BirthdayCheck
DECLARE
v_SeqNo INT;
v_SubSurname CHAR(3);
v_SeqChar VARCHAR(3);
BEGIN
v_SeqNo := childid_sequence.nextval;
v_SubSurname := UPPER(SUBSTR(:NEW.Child_Surname,1,3));
v_SeqChar := TO_CHAR(v_SeqNo);
IF v_SeqNo < 10
THEN
:NEW.ChildID := 'CH' || v_SubSurname || '00' || v_SeqChar;
ELSIF v_SeqNo >= 10 AND v_SeqNo < 100
...
END;
第一个触发器不会引发异常。您正在捕获错误,显示一条消息(if 客户端配置为显示 dbms_output 消息,您不能依赖),然后...异常已被压缩,因此插入继续。
也许您想提出自己的例外;事实上,你说你正在引发一个用户定义的异常,但实际上并非如此。您声明并提出一个,但随后将其压扁。你想做这样的事情:
create or replace TRIGGER BirthdayCheck
BEFORE INSERT ON Child
FOR EACH ROW
BEGIN
IF :NEW.Child_Birthday > SYSDATE
THEN
RAISE_APPLICATION_ERROR(-20000,
'YOU HAVE ATTEMPTED TO INSERT A FUTURE DATE');
END IF;
END;
在我正在创建的数据库中,我有两个触发器,它们都在 table Child
.
BEFORE INSERT
上触发
第一个触发器检查尝试插入的 Child_Birthday
值是否最多为今天;因此,如果值为明天,触发器将引发用户定义的异常。
第二个触发器在第一个触发器之后触发,这将为插入的记录创建自定义 ID 值。
但是,在测试触发器时,我插入了明天的日期,即 15-JAN-15
,该行仍然插入到 table。我假设这是因为第二个触发器仍然触发并插入记录,而不管第一个触发器引发异常(如果我在这里错了请纠正我)。
我想要的是第二个触发器仅在第一个触发器未引发异常时触发。
第一个触发器:
create or replace TRIGGER BirthdayCheck
BEFORE INSERT ON Child
FOR EACH ROW
DECLARE
dateError EXCEPTION;
BEGIN
IF :NEW.Child_Birthday > SYSDATE
THEN
RAISE dateError;
END IF;
EXCEPTION
WHEN dateError
THEN
DBMS_OUTPUT.PUT_LINE('ERROR: YOU HAVE ATTEMPTED TO INSERT A FUTURE DATE');
END;
第二个触发器:
create or replace TRIGGER ChildID
BEFORE INSERT ON Child
FOR EACH ROW
FOLLOWS BirthdayCheck
DECLARE
v_SeqNo INT;
v_SubSurname CHAR(3);
v_SeqChar VARCHAR(3);
BEGIN
v_SeqNo := childid_sequence.nextval;
v_SubSurname := UPPER(SUBSTR(:NEW.Child_Surname,1,3));
v_SeqChar := TO_CHAR(v_SeqNo);
IF v_SeqNo < 10
THEN
:NEW.ChildID := 'CH' || v_SubSurname || '00' || v_SeqChar;
ELSIF v_SeqNo >= 10 AND v_SeqNo < 100
...
END;
第一个触发器不会引发异常。您正在捕获错误,显示一条消息(if 客户端配置为显示 dbms_output 消息,您不能依赖),然后...异常已被压缩,因此插入继续。
也许您想提出自己的例外;事实上,你说你正在引发一个用户定义的异常,但实际上并非如此。您声明并提出一个,但随后将其压扁。你想做这样的事情:
create or replace TRIGGER BirthdayCheck
BEFORE INSERT ON Child
FOR EACH ROW
BEGIN
IF :NEW.Child_Birthday > SYSDATE
THEN
RAISE_APPLICATION_ERROR(-20000,
'YOU HAVE ATTEMPTED TO INSERT A FUTURE DATE');
END IF;
END;