【问题标题】:How to successfully reference another table before insert with a trigger如何在使用触发器插入之前成功引用另一个表
【发布时间】:2021-02-25 09:31:04
【问题描述】:

我正在尝试创建一个触发器来验证表 registraties(注册)中的新条目是否包含有效的 MNR(员工编号),但我在引用表的部分卡住了medewerkers(员工)。

有人可以帮我吗?

CREATE OR REPLACE TRIGGER t_MNRcontrole

BEFORE INSERT OR UPDATE 
ON registraties

DECLARE 
MNR_medewerkers number (SELECT MNR FROM MEDEWERKERS);

FOR EACH ROW
BEGIN 

IF :new.MNR <> MNR_medewerkers
THEN raise_application_error(-20111, 'Medewerker niet herkend!');

END IF;
END;

收到的错误消息是
ORA-24344: success with compilation error

【问题讨论】:

    标签: sql plsql triggers oracle-apex


    【解决方案1】:

    MNR_medewerkers 号码(从 MEDEWERKERS 中选择 MNR);

    总是会失败,因为它不是数字,除非你的表恰好只有一个条目,即使那样我也不确定 PLSQL 是否会允许它通过。

    更标准的情况是首先声明数字,然后在代码块中执行 SELECT INTO 和 WHERE 子句,确保只从表中选择一个特定行。然后您可以将该数字与新数字进行比较。

    但是,如果您不尝试与特定行进行比较,而是检查该条目是否存在于该表中。

    BEGIN
      SELECT 1
        INTO m_variable
        FROM table
       WHERE MNR = :new.MNR;
    EXCEPTION
      WHEN TOO_MANY_ROWS THEN
        m_variable = 1;
      WHEN OTHERS THEN
        m_variable = 0;
    END;
    

    事先声明m_variable,然后检查是否为0则报错。

    too_many_rows 是为了以防表中包含此 MNR 的多行,而 OTHERS 用于 NO_DATA_FOUND,但我使用 OTHERS 来处理可能发生但可能不会发生的所有其他事情。

    顺便说一句,这是一个包含在主代码块中的代码块,因此在您的 BEGIN 和 IF 之间,然后只需更改 IF 以检查变量是否为 0。

    【讨论】:

    • 我觉得你的答案应该有效,但我无法让它发挥作用。澄清一下,MNR 是 medewerkers 中的 PK,我想检查在尝试注册时(在表 registraties 中插入一行),员工 (MNR) 是否已知。如果不是,则显示错误。
    【解决方案2】:

    PL/SQL 赋值运算符是:=,或select x into y from z 以从 SQL 查询中填充。

    FOR EACH ROW 是触发器规范的一部分,而不是 PL/SQL 代码。

    如果父表中不存在:new.mnr,您将得到no_data_found 异常,而不是不匹配的变量。

    错误消息最好包含失败的详细信息。

    在编程中,我们使用缩进来表示代码结构。

    固定版本类似于:

    create or replace trigger trg_mnrcontrole
        before insert or update on registraties
        for each row
    declare
        mnr_medewerkers medewerkers.mnr%type;
    begin
        select mw.mnr into mnr_medewerkers
        from   medewerkers mw
        where  mw.mnr = :new.mnr;
    
    exception  
        when no_data_found then
            raise_application_error(-20111, 'Medewerker '||:new.mnr||' niet herkend!');
    end;
    

    但是,我们可以使用foreign key constraint 更好地实现这种检查,例如:

    alter table registraties add constraint registraties_mw_fk
    foreign key (mnr) references medewerkers.mnr;
    

    【讨论】:

    • 谢谢!我添加了错误代码,实际上我不确定如何缩进,尝试了TAB,但它似乎没有用。刚找到一个网站说可以在设置中更改,所以我会尝试一下。我认为您的解决方案应该有效,我不习惯 SELECT INTO 语句。我仍然熟悉这些可能性。非常感谢您的解释。
    • 触发器不是解决它的最佳方法 - 为此目的存在外键约束。看看那个吧
    • 我不知道你用的是什么编辑器,但我发现 4 个空格就可以了 :)
    猜你喜欢
    • 2021-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多