Может ли JOB динамически создаваться внутри триггера? - PullRequest
2 голосов
/ 04 декабря 2011

Сбой выполнения этого триггера (он компилируется, но как только я выполняю указанную вставку -> ошибка)

create or replace
TRIGGER AFT_INSERT_TMP_TBL
AFTER INSERT ON TMP_TBL
REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW
DECLARE 

    V_SQL VARCHAR2(1000);
    A_NAME VARCHAR2(100);

BEGIN
    A_NAME:='ANY_NAME';

    V_SQL:='BEGIN 
              DBMS_SCHEDULER.CREATE_JOB (
                  job_name => '''||A_NAME||''',
                  job_type => ''PLSQL_BLOCK'',
                  job_action => ''BEGIN DBMS_OUTPUT.PUT_LINE('||A_NAME||'); END;'',
                  start_date => TIMESTAMP''2011-12-4 10:30:00'',
                  repeat_interval => ''FREQ=MINUTELY;INTERVAL=2'',
                  auto_drop => FALSE,
                  comments => '''||A_NAME||''');
            END;';
     DBMS_OUTPUT.PUT_LINE('SCHEDULER :'||V_SQL);
     EXECUTE IMMEDIATE V_SQL;

END AFT_INSERT_TMP_TBL;
-----------------------

Напечатанный код создания SCHEDULER полностью действителен.

Я получаюORA-04092 'не может в триггере ... Триггер попытался зафиксировать или откатить.Перепишите триггер, чтобы он не фиксировался и не откатывался ».

Это «коммит»?Таким образом, JOB не может быть создан внутри триггера?

Я знаю, что использовал триггеры со вставками в разные таблицы, и это тоже "коммит", и Oracle не жаловался.

Ответы [ 3 ]

4 голосов
/ 05 декабря 2011

Вызов DBMS_SCHEDULER.CREATE_JOB неявно фиксирует, поэтому вы не можете создать задание DBMS_SCHEDULER в триггере.Это одна из ситуаций, в которой все еще требуется использование старого пакета DBMS_JOB, поскольку DBMS_JOB.SUBMIT не выполняет неявную фиксацию.

Этот триггер должен создать желаемое задание, используя пакет DBMS_JOB вместо DBMS_SCHEDULER.

create or replace
TRIGGER AFT_INSERT_TMP_TBL
AFTER INSERT ON TMP_TBL
REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW
DECLARE 

    V_SQL VARCHAR2(1000);
    A_NAME VARCHAR2(100);
    l_jobno NUMBER;
BEGIN
    A_NAME:='ANY_NAME';

    dbms_job.submit( l_jobno,
                     'BEGIN dbms_output.put_line( ''' || a_name || ''' ); END;',
                     sysdate + interval '2' minute,
                     'sysdate + interval ''2'' minute' );
     DBMS_OUTPUT.PUT_LINE('Job Number:'||l_jobno);

END AFT_INSERT_TMP_TBL;
2 голосов
/ 11 августа 2014

Вы также можете рассмотреть автономную транзакцию https://community.oracle.com/thread/2399412?start=0&tstart=0

1 голос
/ 04 декабря 2011

Да, это коммит.Oracle обновляет системную таблицу, job$ Я думаю, когда вы создаете планировщик или задание и т. Д., Что означает автоматическое принятие.

Почему бы вам просто не вставить необходимую информацию в другую (драйверную) таблицу и создать задание cron или dbms_job для создания заданий планировщика?

...