舊版 DBMS_JOB 以字串表達式定義間隔,易寫錯且無法精確控制。本文提供 **完整間隔參數對照表**,並推薦遷移至 10g+ **DBMS_SCHEDULER** 以獲得曆法語意、錯誤處理、日誌查詢等企業級功能。
| 需求 | INTERVAL 字串 | 說明 |
|---|---|---|
| 每天午夜 00:00 | 'TRUNC(SYSDATE + 1)' | 翌晨 0 點 |
| 每天 08:30 | 'TRUNC(SYSDATE + 1) + (8*60+30)/(24*60)' | 分鐘轉天數 |
| 每週二中午 12:00 | 'NEXT_DAY(TRUNC(SYSDATE), ''TUESDAY'') + 12/24' | NEXT_DAY 回傳下個周二 00:00 |
| 每月 1 號 00:00 | 'TRUNC(LAST_DAY(SYSDATE) + 1)' | 下個月第一天 |
| 每季最後一天 23:00 | 'TRUNC(ADD_MONTHS(SYSDATE + 2/24, 3), ''Q'') - 1/24' | 季度截斷再減 1 小時 |
| 每週六、日 06:10 | 'TRUNC(LEAST(NEXT_DAY(SYSDATE,''SATURDAY''), NEXT_DAY(SYSDATE,''SUNDAY''))) + (6*60+10)/(24*60)' | 取較早的週末 |
| 每 1 分鐘 | 'SYSDATE + 1/(24*60)' | |
| 每 10 分鐘 | 'SYSDATE + 10/(24*60)' | |
| 每 30 秒 | 'SYSDATE + 30/(24*60*60)' | 高頻慎用 |
| 每 1 小時 | 'SYSDATE + 1/24' | |
| 每 1 週 | 'SYSDATE + 7' | |
| 不再執行並移除 | NULL | DBMS_JOB.REMOVE(job_no) |
| 每年 1 月 1 日 00:00 | 'TRUNC(LAST_DAY(TO_DATE(EXTRACT(YEAR FROM SYSDATE)||''12''||''01'',''YYYY-MM-DD'')) + 1)' | 較複雜,建議用 SCHEDULER |
CREATE OR REPLACE PROCEDURE proc_job_rain_jm IS
l_jobno NUMBER;
BEGIN
DBMS_JOB.SUBMIT(
job => l_jobno,
what => 'PROC_RAIN_JM;', -- 呼叫的存儲過程
next_date => SYSDATE,
interval => 'TRUNC(SYSDATE + 1)' -- 每天午夜
);
COMMIT;
DBMS_OUTPUT.PUT_LINE('Job No: ' || l_jobno);
END;
/
BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'RAIN_JM_DAILY',
job_type => 'STORED_PROCEDURE',
job_action => 'PROC_RAIN_JM',
start_date => SYSTIMESTAMP AT TIME ZONE 'Asia/Taipei',
repeat_interval => 'FREQ=DAILY; BYHOUR=0; BYMINUTE=0; BYSECOND=0', -- 曆法語意
end_date => NULL,
enabled => TRUE,
auto_drop => FALSE,
comments => '每日午夜同步雨量資料'
);
END;
/
FREQ=DAILY; BYHOUR=8; BYMINUTE=30 一眼看懂。TIMEZONE,跨 DST 自動調整。BYMONTHDAY=1,-1 (月初/月末)、BYDAY=MON,TUE、BYHOUR=0-23 任意組合。SELECT * FROM DBA_SCHEDULER_JOB_RUN_DETAILS WHERE JOB_NAME='...';MAX_RUNS, MAX_FAILURES, RESTARTABLE。DBMS_SCHEDULER.CREATE_CHAIN 定義前後依賴。-- 執行歷程
SELECT log_date, status, error#, run_duration
FROM dba_scheduler_job_run_details
WHERE job_name = 'RAIN_JM_DAILY'
ORDER BY log_date DESC;
-- 當前執行中
SELECT * FROM dba_scheduler_running_jobs WHERE job_name = 'RAIN_JM_DAILY';
-- 啟用/停用
EXEC DBMS_SCHEDULER.ENABLE('RAIN_JM_DAILY');
EXEC DBMS_SCHEDULER.DISABLE('RAIN_JM_DAILY');
DBA_JOBS 並記錄 WHAT, INTERVAL。REPEAT_INTERVAL 曆法語意。DBMS_SCHEDULER Job,設定 AUTO_DROP=FALSE。DBMS_JOB.BROKEN(job_no, TRUE) 停用舊 Job → 啟用 Scheduler Job。拋棄難維護的字串間隔,擁抱 DBMS_SCHEDULER 的曆法語意與企業級功能,是 Oracle 排程現代化的必經之路。