ORA-04092: невозможно выполнить ОТКАТ в триггере после превышения количества ежедневных приложений. - PullRequest
0 голосов
/ 30 мая 2020

Могу ли я узнать, как будет написан триггер, если, скажем, есть кандидат, должность, отношения приложений и заявки, это как класс ассоциации, поскольку кандидат может подавать заявки на многие должности, а должность может применяться многими кандидатами, а отношение заявок имеет свой собственный атрибут dateApp, и я хочу ограничить количество приложений до двух раз в день, так что это означает, что клиент может применять только 2 элемента за один день. Пока у меня есть этот код:

CREATE OR REPLACE TRIGGER APPLYTWICEONLY
AFTER INSERT ON APPLIES
DECLARE
CURSOR C IS
SELECT ANUMBER, COUNT(APPDATE) AS TOTAL
FROM APPLIES
WHERE APPDATE = TRUNC(SYSDATE)
GROUP BY ANUMBER;
BEGIN


FOR APPLY IN C
LOOP

   IF APPLY.TOTAL > 2 THEN
      DBMS_OUTPUT.PUT_LINE('AN APPLICANT CAN APPLY MAXIMUM TWICE A DAY.');
      ROLLBACK;
   END IF;
END LOOP;


END;
/

, так что здесь происходит следующее: после того, как кандидат подает заявку на должность, я проверяю общее количество заявок, поданных сегодня для каждого кандидата, используя номер, если общее количество количество заявок превышает 2 для кандидата сегодня, тогда я откатываюсь и отменяю эту вставку. Я хочу сделать это с помощью триггера оператора вместо триггера строки, но я продолжаю получать ORA-04092: невозможно выполнить ОТКАТ в триггере после того, как кандидат превысил количество заявок за день. Кто-нибудь может мне помочь?

Ответы [ 2 ]

1 голос
/ 30 мая 2020

Вы не можете запустить COMMIT или ROLLBACK в триггере:

$ oerr ora 4092
04092, 00000, "cannot %s in a trigger"
// *Cause: A trigger attempted to commit or rollback.
// *Action: Rewrite the trigger so it does not commit or rollback.
$ 
0 голосов
/ 30 мая 2020

Принуждение к бизнес-логам c через триггеры базы данных чаще всего является неправильным подходом.

Вы должны сделать эту проверку, где кандидат подает заявку на должность , и либо позволить ему продолжить, либо остановить заявку процесс.


Поскольку триггеры не могут commit или rollback; ну, это не полностью правда. Если это (триггер) автономная транзакция, то может. Например:

SQL> create or replace trigger trg_rlbk
  2    after insert on test
  3  declare
  4    pragma autonomous_transaction;
  5  begin
  6    rollback;
  7  end;
  8  /

Trigger created.

SQL> insert into test (id) values (2);

1 row created.

SQL> select * From test;

        ID NAME
---------- --------------------
         2

SQL>

Как видите, основная транзакция не откатилась - ID = 2 было вставлено в таблицу. То, что было бы отменено, было бы кодом, содержащимся в самом триггере. В моем примере нет ничего, чтобы показать вам, что такая прагма не поможет в том, что вы пытаетесь сделать.

Кроме того, вы можете что-то не означает, что вы должны это сделать.

...