2011-12-04 93 views
1

這個觸發器執行失敗(它編譯但一旦我做指定的插入 - >錯誤)JOB是否可以在觸發器內動態創建?

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

印刷調度器創建代碼是完全有效的。

我得到一個ORA-04092'不能在觸發器...一個觸發器試圖提交或回滾。重寫觸發器,使其不提交或回滾'。

這是'提交'嗎?所以一個JOB不能在觸發器內創建?

我知道我已經使用觸發器插入到不同的表中,這也是一個「提交」 和Oracle沒有投訴。

回答

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

是的,這是一個提交。 Oracle正在更新一個系統表,job$我認爲,當你創建一個調度程序或一個工作等等,這意味着一個自動提交。

爲什麼不直接將需要的信息插入另一個驅動程序表中並使用cron作業或dbms_job來創建您的調度程序作業?

相關問題