从触发器调用程序来验证生日
Invoking procedure from a trigger to validate birthdate
我在下面创建了一个触发器 (Trig 1) 以在插入员工 table 之前触发。然后此触发器将调用过程 (Proc 1),该过程将验证生日不早于当前日期。如果不继续插入,但如果日期早于当前日期,它将显示一条消息,如 "invalid birthdate"。
(触发 1)
create or replace trigger VALIDATE_BDAY_TRIG
before insert on employee
for each row
declare
birth_date date;
employee_birthdate date;
begin
birth_date := employee_birthdate;
val_bday_proc birth_date;
end VALIDATE_BDAY_TRIG;
(过程 1)
create or replace procedure val_bday_proc(
date_of_birth in date)
as
begin
if date_of_birth > current_date()
then raise_application_error(-20000, 'Employee birth date should not be earlier than the current date');
end;
调用存储过程时,应在括号内传递变量:
val_bday_proc(birth_date)
此外,您需要获取要插入的实际值,因为现在 employee_birthdate
只是一个变量,将是 null
。您可以使用 :new.fieldname
来获取新记录的字段 'fieldname' 的值。根本不需要为此声明变量,因此您的触发器可能看起来像这样,假设该字段被称为 employee_birthdate
:
Create or Replace trigger VALIDATE_BDAY_TRIG
before insert on employee
for each row
begin
val_bday_proc(:new.employee_birthdate);
end VALIDATE_BDAY_TRIG;
存储过程似乎没问题,只是缺少 end if;
来关闭 if 语句。
一些旁注:
- 你好像前前后后都糊涂了。 proc 中的代码没问题,但在错误消息和问题文本中你得到了相反的结果。
- 您可以(也许应该?)也可以在更新时检查此项,否则您可以插入一个较早的日期,然后将其更新为将来的某个日期。您可以为此创建一个单独的触发器,或修改当前触发器以在更新时也触发:(
before insert or update
).
- 为显示上下文的触发器制定命名约定可能会有所帮助(无论它们是插入 and/or 更新、行级别还是语句级别)。如果您有多个触发器,这可以帮助您找到合适的触发器。
- 至少考虑完全不将其放入触发器中是个好主意。我从惨痛的教训中了解到,在触发器中包含大量业务逻辑最终会影响性能,难以调试,也难以更改。这些类型的检查可以在存储员工数据的应用层中进行。
我在下面创建了一个触发器 (Trig 1) 以在插入员工 table 之前触发。然后此触发器将调用过程 (Proc 1),该过程将验证生日不早于当前日期。如果不继续插入,但如果日期早于当前日期,它将显示一条消息,如 "invalid birthdate"。 (触发 1)
create or replace trigger VALIDATE_BDAY_TRIG
before insert on employee
for each row
declare
birth_date date;
employee_birthdate date;
begin
birth_date := employee_birthdate;
val_bday_proc birth_date;
end VALIDATE_BDAY_TRIG;
(过程 1)
create or replace procedure val_bday_proc(
date_of_birth in date)
as
begin
if date_of_birth > current_date()
then raise_application_error(-20000, 'Employee birth date should not be earlier than the current date');
end;
调用存储过程时,应在括号内传递变量:
val_bday_proc(birth_date)
此外,您需要获取要插入的实际值,因为现在 employee_birthdate
只是一个变量,将是 null
。您可以使用 :new.fieldname
来获取新记录的字段 'fieldname' 的值。根本不需要为此声明变量,因此您的触发器可能看起来像这样,假设该字段被称为 employee_birthdate
:
Create or Replace trigger VALIDATE_BDAY_TRIG
before insert on employee
for each row
begin
val_bday_proc(:new.employee_birthdate);
end VALIDATE_BDAY_TRIG;
存储过程似乎没问题,只是缺少 end if;
来关闭 if 语句。
一些旁注:
- 你好像前前后后都糊涂了。 proc 中的代码没问题,但在错误消息和问题文本中你得到了相反的结果。
- 您可以(也许应该?)也可以在更新时检查此项,否则您可以插入一个较早的日期,然后将其更新为将来的某个日期。您可以为此创建一个单独的触发器,或修改当前触发器以在更新时也触发:(
before insert or update
). - 为显示上下文的触发器制定命名约定可能会有所帮助(无论它们是插入 and/or 更新、行级别还是语句级别)。如果您有多个触发器,这可以帮助您找到合适的触发器。
- 至少考虑完全不将其放入触发器中是个好主意。我从惨痛的教训中了解到,在触发器中包含大量业务逻辑最终会影响性能,难以调试,也难以更改。这些类型的检查可以在存储员工数据的应用层中进行。