触发神谕:怎么了?

Trigger oracle: whats wrong?

这是我的代码:

create trigger TriggerAdresse1
    before INSERT
    on Adresse
    for each row
declare
    enthaelt boolean;
begin
    if ((Provinz in (select Name from Provinz2)) and (Laendercode in (select Laendercode from Provinz2))) then
        enthaelt := true;
    end if;
    if(enthaelt:=false) then
        rollback;
    end if;
end;

如果属性 Provinz 或 Laendercode 不在 table Provinz2 中,我将尝试取消插入。 Datagrip 说它无效...

感谢您的帮助! 最好的问候

我认为您打算检查插入的值,所以您真的打算:

begin
    enthaelt := false;
    if ((:new.Provinz in (select Name from Provinz2)) and (:new.Laendercode in (select Laendercode from Provinz2))) then
        enthaelt := true;
    end if;
    if(enthaelt:=false) then
        rollback;
    end if;
end;

您还需要初始化变量。

也就是说,实现此逻辑的正确方法是使用外键约束。很遗憾,您被教导使用触发器进行此检查。

  • 一个BOOLEAN值在Oracle中可以有三个值:TRUEFALSENULL,你没有初始化变量。
  • 您必须引用新值(默认为 :new
  • 默认情况下,触发器不能包含 COMMITROLLBACK

您的代码必须是这样的:

create trigger TriggerAdresse1
    before INSERT
    on Adresse
    for each row
declare
    enthaelt INTEGER;
begin

    SELECT COUNT(*)
    INTO enthaelt 
    FROM Provinz2
    WHERE Name = :new.Provinz
       AND Laendercode = :new.Laendercode;
    if enthaelt = 0 then
        RAISE_APPLICATION_ERROR(-20001, 'Provinz oder Ländercode ungültig');
    end if;
end;

但是,您的要求应该使用 FOREIGN KEY 约束更好地实现

alter table Adresse add constraint Provinz_FK FOREIGN KEY (Provinz) 
  references Provinz2 (Name);

alter table Adresse add constraint Laendercode_FK FOREIGN KEY (Laendercode) 
  references Provinz2(Laendercode);

很可能 Laendercode 不是 UNIQUE 键,但 Name+Laendercode 是。那么它会是这样的:

alter table Adresse add constraint Provinz_FK FOREIGN KEY (Provinz, Laendercode) 
  references Provinz2 (Name, Laendercode);

if(enthaelt:=false) then 通过此语句,您的意图是执行比较,但是 := 执行分配。所以每当你比较时,你应该使用如下:

if(enthaelt=false) then