可以在触发器内动态创建JOB吗?

时间:2011-12-04 14:24:17

标签: oracle commit 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);

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 个答案:

答案 0 :(得分:4)

调用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;

答案 1 :(得分:2)

答案 2 :(得分:1)

是的,这是一个提交。在我创建调度程序或作业等时,Oracle正在更新系统表job$,这意味着自动提交。

为什么不直接将所需信息插入另一个(驱动程序)表并使用cron作业或dbms_job来创建调度程序作业?