从触发器调用过程以验证生日

Posted

技术标签:

【中文标题】从触发器调用过程以验证生日【英文标题】:Invoking procedure from a trigger to validate birthdate 【发布时间】:2018-11-26 13:33:42 【问题描述】:

我在下面创建了一个触发器(Trig 1),以便在插入员工表之前触发。然后此触发器将调用过程 (Proc 1),该过程将验证出生日期不早于当前日期。如果不继续插入,但如果日期早于当前日期,它将显示一条消息,如“无效的生日”。 (触发 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;

【问题讨论】:

在编译上面的触发器时,我得到了这个错误:错误(9,23):PLS-00103:在期待以下之一时遇到符号“BIRTH_DATE”::=。 ( @ % ; 符号 ":=" 被替换为 "BIRTH_DATE" 以继续。 我也不确定我的程序是否可行。 请将问题放在问题中,而不是在 cmets..(点击“编辑”以编辑问题)。 对不起,我的错。只是一个新成员。 【参考方案1】:

调用存储过程时,应在括号之间传递变量:

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)。 为显示其上下文的触发器制定一个命名约定可能会有所帮助(无论它们是插入和/或更新、行级别还是语句级别)。如果您有多个触发器,这有助于您找到正确的触发器。 至少考虑不把它放在触发器中是个好主意。我了解到,触发器中有很多业务逻辑最终会影响性能,很难调试,也很难改变。此类检查可以在存储员工数据的应用层中进行。

【讨论】:

我只是想澄清一下,我的表中的实际字段名是employee_birthdate。所以我将您提供的答案编辑到 val_bday_proc(:new.employee_birthdate);并出现错误:Error(5,3): PLS-00905: object SYSTEM.VAL_BDAY_PROC is invalid

以上是关于从触发器调用过程以验证生日的主要内容,如果未能解决你的问题,请参考以下文章

验证码---短信验证码

如何从 AJAX 调用触发浏览器的基本身份验证对话框?

VueJS验证没有触发第一次调用

从 MySQL 触发器调用 PHP 脚本

Oracle 学习之触发器

调用经过用户身份验证的 http 触发器时发生错误