SQL> CREATE TABLE test (a DATE);
Table created.
SQL> CREATE OR REPLACE PROCEDURE myproc AS
2 BEGIN
3 INSERT INTO test VALUES (SYSDATE);
4 END;
5 /
Procedure created.
SQL> VARIABLE job1 NUMBER;
SQL> BEGIN
2 DBMS_JOB.SUBMIT(
3 job => :job1,
4 what => 'myproc;',
5 next_date => SYSDATE,
6 interval => 'SYSDATE + 1/1440' -- 1 天 = 1440 分鐘
7 );
8 COMMIT;
9 END;
10 /
PL/SQL procedure successfully completed.
SQL> PRINT job1
JOB1
----------
14144
SQL> BEGIN
2 DBMS_JOB.RUN(:job1);
3 END;
4 /
PL/SQL procedure successfully completed.
SQL> SELECT TO_CHAR(a, 'YYYY/MM/DD HH24:MI:SS') "執行時間" FROM test;
執行時間
-------------------
2001/01/07 23:51:21
2001/01/07 23:52:22
2001/01/07 23:53:24
每分鐘精確執行一次,驗證成功。
SQL> BEGIN
2 DBMS_JOB.REMOVE(:job1);
3 COMMIT;
4 END;
5 /
PL/SQL procedure successfully completed.
| 操作 | 關鍵語法 | 注意事項 |
|---|---|---|
| 提交 | DBMS_JOB.SUBMIT(:job, 'proc;', SYSDATE, 'SYSDATE+1/1440') | INTERVAL 必須為字串運算式,以「上次啟動時間」為基準計算下次 |
| 立即執行 | DBMS_JOB.RUN(:job) | 同步執行,會阻塞至完成;非同步請用 DBMS_SCHEDULER.RUN_JOB(..., USE_CURRENT_SESSION=>FALSE) |
| 查詢 | SELECT * FROM USER_JOBS | 含 NEXT_DATE、FAILURES、BROKEN、WHAT |
| 刪除 | DBMS_JOB.REMOVE(:job) | 需 COMMIT 生效 |
'SYSDATE + 1/24':每小時 (1/24 天)'SYSDATE + 1/1440':每分鐘 (1/1440 天)'TRUNC(SYSDATE+1) + 6/24':每天凌晨 06:00'NEXT_DAY(TRUNC(SYSDATE), ''MONDAY'') + 9/24':每週一 09:00'ADD_MONTHS(TRUNC(SYSDATE,''MM''),1) + 2/24':每月 1 號 02:00缺點:以「上次實際啟動時間」為基準,若執行耗時長或系統忙碌導致延遲,後續排程會逐漸漂移。DBMS_SCHEDULER 的 REPEAT_INTERVAL 採固定時刻表 (Calendaring Syntax),無漂移問題。
| 錯誤 | 原因 | 解決 |
|---|---|---|
| ORA-23421: job number not found | Job Number 錯誤或已刪除 | 確認 USER_JOBS 存在的 Job Number |
| ORA-04068: existing state of packages has been discarded | Procedure 重新編譯導致狀態失效 | 重新提交 Job 或重新連線 |
| Job 不執行 | JOB_QUEUE_PROCESSES = 0 | ALTER SYSTEM SET JOB_QUEUE_PROCESSES = 10 |