La 10 et la 11g offrent un nouveau package pour gérer les jobs : DBMS_SCHEDULER en remplacement de DBMS_JOB (voir en fin d’article une migration, ou un résumé des changement de l’un à l’autre extrait de la doc officielle.
Plusieurs avantages :
- une gestion des droits plus fine,
- des jobs nommés (finis les job_id peu explicites),
- une gestion des intervalles de temps simplifiée (finis les calculs savants avec SYSDATE mais une frequence horaire, hebdomadaire, mensuelle,…)
Prerequis
Qu’il existe au moins une JOB QUEUE et le process associé
SQL> SHOW PARAMETER JOB
ou
SQL> select name
from v$bgprocess
where name like ‘CJQ%’
Le user créateur du JOB doit aussi avoir le privilège system ‘CREATE JOB’ …ou etre DBA
Infos minimales pour créer / planifier un JOB
Job Name: le nom du job (unique / aux noms d’objets)
Job Type: 3 types possibles : PLSQL_BLOCK, STORED_PROCEDURE, EXECUTABLE. .
Job Action: un bloc, un nom de proc, ou un chemin complet d’executable
Start Date: date de debut (la 1ere fois ou le job s’execute , format : TIMESTAMP WITH TIME ZONE
Enabled: TRUE ou FALSE. Attention !!! par default le job est créé DISABLED
Repeat Interval: intervalle de répétition. On peut utiliser l’aritmetique de date ‘old style’ comme avec DBMS_JOB, ou préférablement la notion de fréquence :
exemple :FREQ=WEEKLY;BYDAY=MON,THU;BYHOUR=18;BYMINUTE=0
les valeurs possibles sont BYMONTH, BYMONTHDAY, BYYEARDAY, BYDAY, BYHOUR, BYMINUTE, BYWEEKNO
On peut facilement tester l’execution en lancant le Job sans attendre…
exec DBMS_SCHEDULER.run_job (job_name => ‘job_dd’);
Création d’un Job
On utilise le package DBMS_SCHEDULER et la procédure CREATE_JOB
BEGIN
DBMS_SCHEDULER.create_job (
job_name => ‘job_dd’,
job_type => ‘PLSQL_BLOCK’,
job_action => ‘BEGIN NULL; /* a fe ren */ END;’,
start_date => SYSTIMESTAMP,
repeat_interval => ‘FREQ=DAILY’,
enabled => TRUE,
comments => ‘c est pas obligatoire mais un bon commentaire…’);
END;
/
– SUPPRESSION
exec DBMS_SCHEDULER.drop_job (job_name => ‘job_dd’ );
remarque : si l’on ne veut pas supprimer un JOB définitivement mais simplement empechere son activation pendant un certain temps, on peut mettre son statut à DISABLED :
dbms_scheduler.disable
Des infos dans le dictionnaire ?
A minima
SQL> select job_name, enabled
from user_scheduler_jobs;
ou avec un peu plus de détails sur la planification
SQL> select JOB_NAME , JOB_CREATOR , JOB_TYPE , JOB_ACTION , STATE ,
START_DATE , REPEAT_INTERVAL , LAST_START_DATE , NEXT_RUN_DATE
FROM USER_SCHEDULER_JOBSJOB_NAME JOB_CREATOR JOB_TYPE JOB_ACTION STATE START_DATE REPEAT_INTERVAL NEXT_RUN_DATE
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
JOB_DD SYSTEM PLSQL_BLOCK BEGIN NULL;END; SCHEDULED 08-SEP-08 11.00.03 FREQ=DAILY 09-SEP-08 11.00.03
mais aussi les vues
DBA_SCHEDULER_SCHEDULES - informations sur les jobs planifiés courants
DBA_SCHEDULER_PROGRAMS , DBA_SCHEDULER_PROGRAM_ARGS - informations sur les programmes
De DBMS_JOB à DBMS_SCHEDULER
créer un Job
VARIABLE jobno NUMBER;
BEGIN
DBMS_JOB.SUBMIT(:jobno, ‘INSERT INTO employees VALUES (7935, ”SALLY”,
”DOGAN”, ‘’sally.dogan@xyzcorp.com”, NULL, SYSDATE, ”AD_PRES”, NULL,
NULL, NULL, NULL);’, SYSDATE, ‘SYSDATE+1′);
COMMIT;
END;
/
equivalent statement using DBMS_SCHEDULER is the following:
BEGIN
DBMS_SCHEDULER.CREATE_JOB(
job_name => ‘job1′,
job_type => ‘PLSQL_BLOCK’,
job_action => ‘INSERT INTO employees VALUES (7935, ”SALLY”,
”DOGAN”, ‘’sally.dogan@xyzcorp.com”, NULL, SYSDATE,”AD_PRES”, NULL,
NULL, NULL, NULL);’);
start_date => SYSDATE,
repeat_interval => ‘FREQ = DAILY; INTERVAL = 1′);
END;
Modifier un Job
BEGIN
DBMS_JOB.WHAT(31, ‘INSERT INTO employees VALUES (7935, ”TOM”, ”DOGAN”,
”tom.dogan@xyzcorp.com”, NULL, SYSDATE,”AD_PRES”, NULL,
NULL, NULL, NULL);’);
COMMIT;
END;
/
equivalent à
BEGIN
DBMS_SCHEDULER.SET_ATTRIBUTE(
name => ‘JOB1′,
attribute => ‘job_action’,
value => ‘INSERT INTO employees VALUES (7935, ”TOM”, ”DOGAN”,
”tom.dogan@xyzcorp.com”, NULL, SYSDATE, ”AD_PRES”, NULL,
NULL, NULL, NULL);’);
END;
/
supprimer un Job de la Job Queue
BEGIN
DBMS_JOB.REMOVE(14144);
COMMIT;
END;
/
équivallent à
BEGIN
DBMS_SCHEDULER.DROP_JOB(’myjob1′);
END;
/