Триггер PLSQL не работает 0 вставленных строк - PullRequest
0 голосов
/ 25 июня 2019

Что бы я ни делал для триггера, всегда возвращается "0 строк вставлено". Как будто он не может найти новые значения после их вставки. После добавления исключения возвращается no_data_found, и я не знаю почему.

before insert or update of rent_date, return_date on rent
for each row
declare

pragma AUTONOMOUS_TRANSACTION;

v_rentDate date;
v_returnDate date;


begin
 select rent_date 
   into v_rentDate
   from rent
  where rent_date = :new.rent_date;


  select return_date
    into v_returnDate
    from rent
   where return_date = :new.return_date;


if v_returnDate < v_rentDate then
  raise_application_error(-20158, 'Return date must be after the rent date');
else
  dbms_output.put_line('TEST');
end if;

  exception when no_data_found then raise_application_error(-20157, 'No data found');

end;
/


insert into rent values (82,sysdate-5,101,sysdate,sysdate+5,100);
--0 rows inserted

1 Ответ

1 голос
/ 25 июня 2019

Похоже, вы делаете это неправильно. И вот почему:

  • вы пытаетесь выбрать значения из таблицы, в которую вы в настоящее время вставляете (или обновляете существующие значения)
  • Oracle жалуется, что не может этого сделать, потому что таблица мутирует
  • чтобы «исправить» это, вы использовали прагму autonomous_transaction, которая изолирует код триггера от основной транзакции

Вы не должны использовать эту прагму для такой цели. К счастью, триггер можно переписать более простым способом, который не вызывает ошибку таблицы мутаций. Если вы хотите сравнить rent_date и return_date, сделайте это напрямую. Вот пример (см. Строку № 5):

SQL> create table rent
  2    (id           number,
  3     rent_date    date,
  4     return_date  date
  5    );

Table created.

SQL> create or replace trigger trg_biu_rent
  2    before insert or update on rent
  3    for each row
  4  begin
  5    if :new.return_date < :new.rent_date then
  6       raise_application_error (-20158, 'Return date must be after the rent date');
  7    end if;
  8  end;
  9  /

Trigger created.

Тестирование:

SQL> -- This will fail
SQL> insert into rent (id, rent_date, return_date) values
  2    (1, date '2019-05-25', date '2019-04-10');
insert into rent (id, rent_date, return_date) values
            *
ERROR at line 1:
ORA-20158: Return date must be after the rent date
ORA-06512: at "SCOTT.TRG_BIU_RENT", line 3
ORA-04088: error during execution of trigger 'SCOTT.TRG_BIU_RENT'


SQL> -- This is OK
SQL> insert into rent (id, rent_date, return_date) values
  2    (1, date '2019-03-28', date '2019-10-20');

1 row created.

SQL>
...