Триггер oracle: что не так? - PullRequest
0 голосов
/ 16 января 2020

Это мой код:

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 отсутствует в таблице Provinz2. Datagrip говорит, что это недействительно ...

Спасибо за вашу помощь! С уважением

Ответы [ 3 ]

2 голосов
/ 16 января 2020
Значение
  • A BOOLEAN в Oracle может иметь значения три : TRUE, FALSE и NULL, переменная не инициализирована.
  • Вы должны обратиться к новым значениям (по умолчанию с :new)
  • По умолчанию триггер не может содержать COMMIT или ROLLBACK

Ваш код должен быть таким:

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 Constraint

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 не является УНИКАЛЬНЫМ ключом, но Name+Laendercode является. Тогда было бы так:

alter table Adresse add constraint Provinz_FK FOREIGN KEY (Provinz, Laendercode) 
  references Provinz2 (Name, Laendercode);
0 голосов
/ 24 января 2020

if(enthaelt:=false) then С помощью этого утверждения вы намерены провести сравнение, однако := выполняет задание. Поэтому, когда вы сравниваете, вы должны использовать как показано ниже:

if(enthaelt=false) then
0 голосов
/ 16 января 2020

Я думаю, что вы намереваетесь проверить вводимые значения, поэтому вы действительно намерены:

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;

Вам также нужно инициализировать переменную.

Тем не менее, правильный способ реализации этого logi c с ограничением внешнего ключа. Печально, что вас учат делать эту проверку с помощью триггера.

...