Oracle триггер, указывающий на одну ячейку для обновления - PullRequest
0 голосов
/ 26 мая 2020


Я создал простую таблицу с именем test1, как показано ниже:

enter image description here

Я собираюсь обновить столбец END_SESSION где вы можете видеть нулевое значение, поэтому оператор обновления должен быть таким:
UPDATE test1 SET end_session = 3500, где end_session имеет значение null

Однако идея состоит в том, чтобы избежать условия где в операторе UPDATE и создать триггер, чтобы указать, какая ячейка должна быть обновлена ​​(должно быть нулевым). Я создал триггер:

create or replace trigger updateEND_SESSION
before update of end_session on test1
for each row
declare
    lastROW number;
begin
    select max(NUMER_ID) into lastROW
    from TEST1;
    UPDATE TEST1
    SET END_SESSION = :NEW.END_SESSION
    WHERE NUMER_ID = lastROW;
end;

, но я вижу следующую ошибку:
SQL Ошибка: ORA-04098: триггер «MMDMANAGER.UPDATEENDSESSION» недействителен и не прошел повторную проверку

Кто-нибудь знает, как создать такой триггер?

Ответы [ 2 ]

0 голосов
/ 26 мая 2020

В качестве альтернативы можно написать триггер для предотвращения изменения уже существующих значений:

create or replace trigger trg_update_end_session
before update of end_session on test1
for each row
begin
  if :new.end_session <> :old.end_session then
     raise_application_error(-20000, 'end_session must not be changed');
  end if;
end;

Тогда

update test1 set end_session = 3500;

завершится ошибкой. Вам нужно будет написать

update test1 set end_session = 3500 where end_session is null;

или предоставить сохраненную процедуру

create or replace procedure update_end_session(v_value integer) as
begin
  update test1 set end_session = v_value where end_session is null;
end;
0 голосов
/ 26 мая 2020

Это звучит как плохая идея. Вы должны написать обновление для всех строк, и триггер защитит любые уже существующие значения от перезаписи. Это большая работа для СУБД, потому что все строки обновляются, только большинство из них имеют значение, которое у них уже есть.

Это будет код:

create or replace trigger trg_update_end_session
before update of end_session on test1
for each row
begin
  if :old.end_session is not null then
    :new.end_session := old.end_session;
  end if;
end;

Оператор

update test1 set end_session = 3500;

тогда установит только end_session на 3500, где раньше он был нулевым.

...