2008年8月5日 星期二

Running External Jobs with DBMS_SCHEDULER using Oracle10g


/*
 1) 製作一個 DOS Batch Test.bat。內容為:執行一個test.sql對index做rebuild
 2) 給定權限 CREATE JOB,CREATE EXTERNAL JOB,MANAGE SCHEDULER
 3) 給定時區 DEFAULT_TIMEZONE
 4) 啟動服務 OracleJobScheduler
 5) CREATE_PROGRAM
 6) CREATE_SCHEDULE
 7) CREATE_JOB
 8) 手動 RUN_JOB
 9) 從 ALL_SCHEDULER_JOB_RUN_DETAILS 看執行結果
 10) 將JOB,SCHEDULE,PROGRAM移除
*/

  1) test.bat/test.sql
    test.bat內容:

sqlplus orion/orion @c:\test.sql

    test.sql內容只對一個index做rebuild:

ALTER INDEX TBLBASE_IDX REBUILD;
EXIT

  2) 改以dba身份登入給定權限

SQL> connect / as sysdba
已連線.

SQL>GRANT CREATE JOB TO ORION;

順利授權.

SQL>GRANT CREATE EXTERNAL JOB TO ORION;

順利授權.

SQL>GRANT MANAGE SCHEDULER TO ORION;

順利授權.

  3) 回到user身份來設定DEFAULT_TIMEZONE

SQL>exec dbms_scheduler.set_scheduler_attribute('DEFAULT_TIMEZONE','ROC');

已順利完成 PL/SQL 程序.

  4) 啟動服務

  服務一定要起動,否則external job在執行時會失敗並出現以下錯誤:
ORA-27370: 工作僕站無法啟動類型為 EXECUTABLE 的工作ORA-27300: OS 系統相依作業:accessing execution agent 失敗, 狀態: 2
ORA-27301: OS 失敗訊息: ?t?Χ????w?????C
ORA-27302: 失敗發生於: sjsec 6a
ORA-27303: 額外資訊: ?t?Χ????w?????C


  「開始」→「設定」→「控制台」→「控制台」→「系統管理工具」→「服務」找OracleJobScheduler + SID 的服務將之啟動

  5) CREATE PROGRAM內容如下,並存成crtprg.sql

begin
  dbms_scheduler.create_program (
    program_name => 'testbatchfile',
    program_type => 'EXECUTABLE',
    program_action => 'c:\test.bat',
    number_of_arguments => 0,
    enabled => true,
    comments => '');
 commit;
END;
/

SQL> @c:\crtprg.sql

已順利完成 PL/SQL 程序.

  6) CREATE SCHEDULE內容如下,並存成crtsch.sql
    我只想執行一次因此將repeat_interval及end_date設為null
    另外,start_date如果為null或過期,CREATE_JOB即使完成,
    all_scheduler_jobs裡也不會有這個JOB的資料


begin
  dbms_scheduler.create_schedule (
    schedule_name => 'schedule_testbatchfile',
    start_date => '10-8月 -08 06.00.00.000000000 下午 ROC',
    repeat_interval => NULL,
    end_date => NULL,
    comments => '');
  COMMIT;
END;
/

SQL> @c:\crtsch.sql

已順利完成 PL/SQL 程序.

  7) CREATE JOB內容如下,並存成crtjob.sql

begin
  dbms_scheduler.create_job (
    job_name => 'job_testbatchfile',
    program_name => 'testbatchfile',
    schedule_name => 'schedule_testbatchfile',
    enabled => TRUE,
    comments => '');
  COMMIT;
END;
/

SQL> @c:\crtjob.sql

已順利完成 PL/SQL 程序.

    檢查一下JOB_TESTBATCHFILE是否CREATE成功

SQL> select job_name from all_scheduler_jobs;

JOB_NAME
------------------------------------------------------------
JOB_TESTBATCHFILE


  8) 手動執行->RUN_JOB

SQL> exec dbms_scheduler.run_job(job_name => 'JOB_TESTBATCHFILE',use_current_session => FALSE);

已順利完成 PL/SQL 程序.

  9) 檢查執行結果


SQL> SELECT JOB_NAME,STATUS,
 2     TO_CHAR(LOG_DATE,'YYYY-MM-DD-HH:MI:SS') LOG_DATE
 3 FROM ALL_SCHEDULER_JOB_RUN_DETAILS
 4 WHERE JOB_NAME = 'JOB_TESTBATCHFILE'
 5 AND TO_CHAR(LOG_DATE,'YYYYMMDD') >= '20080807'
 6 ORDER BY LOG_DATE;

JOB_NAME        STATUS    LOG_DATE
-------------------- ----------- ------------------------------------
JOB_TESTBATCHFILE   SUCCEEDED  2008-08-07-11:36:15

  DOUBLE CHECK INDEX是否有被異動(p.s謝謝Betty)

SQL> SELECT OBJECT_NAME,
 2     TO_CHAR(LAST_DDL_TIME,'yyyy-mm-dd-hh:mi:ss') LAST_DDL_TIME
 3 FROM ALL_OBJECTS WHERE OBJECT_NAME = 'TBLBASE_IDX';

OBJECT_NAME      LAST_DDL_TIME
-------------------  --------------------------------------
TBLBASE_IDX      2008-08-07-11:36:15



  10) 移除JOB,SCHEDULE,PROGRAM

SQL>exec dbms_scheduler.drop_job(job_name => 'JOB_TESTBATCHFILE');

已順利完成 PL/SQL 程序.

SQL>exec dbms_scheduler.drop_schedule(schedule_name => 'SCHEDULE_TESTBATCHFILE');

已順利完成 PL/SQL 程序.

SQL>exec dbms_scheduler.drop_program(program_name => 'testbatchfile');

已順利完成 PL/SQL 程序.