Tags:
create new tag
, view all tags


Allgemeines

DBMS Jobs sind Programme, welche periodisch auf der Oracle Datenbank ablaufen und dabei einige Dinge verrichten. Die Programme sind in der Oracle-Programmiersprache PL/SQL geschrieben und sind direkt im Data-Dictionary der Datenbank gespeichert - meist in Form einer "procedure".


Aktive Jobs

Die allermeisten DBMS-Jobs laufen 1x täglich (mit Ausnahme von update_mobile_certified, welcher 10x pro Stunde läuft). Die untenstehende Liste kann mit einem SQL-Skript weiter unten erstellt werden.

Job-Nummer Procedure Zeit
429 update_primary_nuid; 19:25
430 sync_orgstruktur; 16:45
431 sync_doz_periode; 17:20
432 update_mobile_certified; 10x pro Stunde
433 update_pdb_addresses; 17:00
434 grant_mac_service; 07:10
435 sync_anstellung; 17:10
436 sync_einschreibung; 17:20
437 map_doz_periode_to_ngroup; 07:20
438 up_person; 17:30
439 sync_nethz_person; 17:35
440 update_gebaeudeadresse; 18:50
441 do_check_company_department; 18:00
442 sync_immatrikulation; 17:15
569 sync_ethnahe; 17:05
609 map_anstellung_to_ngroup; 17:25
629 sync_beziehung; 13:00
649 map_orgstruktur_to_ngroup; 16:50
669 map_beziehung_to_person; 13:05
670 map_beziehung_to_ngroup; 13:10


Einen DBMS Job einrichten

Um einen DBMS Job in der Datenbank einzurichten, braucht man zwei Dinge:

  1. Eine Prozedur (procedure)
  2. Einen Jobauftrag

Hier ist das Beispiel des Jobs UPDATE_DOZENT_DEPARTEMENT, welcher täglich Dozenten ohne feste Anstellung einem Departement zuweist. Wenn man dieses Skript in einem SQL*Plus Fenster laufenlässt, wird eine entsprechende (kompilierte) Prozedur in das Schema des entsprechenden DB-Users (hier: nethz) geschrieben:

CREATE OR REPLACE PROCEDURE "UPDATE_DOZENT_DEPARTEMENT"
    IS
BEGIN

   update PERSON p
      set DEPARTMENT = (select DEPT_KUERZEL from DLDB_DOZ_PERIODE dp
                         where p.PERSID = dp.PERSID
                           and GUELTIG_VON <= sysdate
                           and GUELTIG_BIS >  sysdate
                           and rownum < 2)
    where (p.IS_LECTURER = 1 or p.IS_EMERITUS = 1)
      and p.IS_EMPLOYEE = 0;

END;
/

Für den Jobauftrag brauchen wir im Wesentlichen 3 Angaben:

  1. Welche Prozedur soll ausgeführt werden?
  2. Wann soll die Prozedur das erste Mal ausgeführt werden?
  3. In welchem Intervall soll die Prozedur laufen?

Hier ist das Skript, welches den Job in die Datenbank einbaut:

DECLARE
  X NUMBER;
BEGIN
  SYS.DBMS_JOB.SUBMIT
    ( job       => X 
     ,what      => 'UPDATE_DOZENT_DEPARTEMENT;'
     ,next_date => to_date('30.05.2006 00:00:00','dd/mm/yyyy hh24:mi:ss')
     ,interval  => 'TRUNC(SYSDATE+1)'
     ,no_parse  => TRUE
    );
  SYS.DBMS_OUTPUT.PUT_LINE('Job Number is: ' || to_char(x));
END;
/

commit;

Das commit am Ende wird gebraucht, da auch ein DBMS-Job im Grunde nichts anderes als ein Tabelleneintrag ist (der durch das Package SYS.DBMS_JOB.SUBMIT bewerkstelligt wird).


Einen Job "offline" nehmen

Um einen Job temporär ausser Betrieb zu nehmen, muss man das Flag broken auf "TRUE" setzen. Dazu muss man die Jobnummer wissen. Falls man sie vergessen hat, kann man sie mit dem SQL-Statement

SELECT job, SUBSTR(what,1,45), next_date, broken
  FROM ALL_JOBS
  WHERE schema_user = 'NETHZ'

herausfinden. Mit dem Statement

BEGIN
  DBMS_JOB.BROKEN(123, TRUE);
END;
/

kann man anschliessend den Job No. 123 ausser Kraft setzen. Mit dem Statement

BEGIN
  DBMS_JOB.BROKEN(123, FALSE);
END;
/

setzt man den Job No. 123 wieder in Kraft. Nach dem FALSE-Statement kann auch noch ein Datum mitgegeben werden:

BEGIN
  DBMS_JOB.BROKEN(123, FALSE, NEXT_DAY(SYSDATE, 'MONDAY'));
END;
/

Job-Liste erstellen (für diese TWiki-Seite)

SELECT '| *Job-Nummer* | *Procedure* | *Zeit* |' line
  FROM DUAL
union
SELECT '| ' || job || ' | ' || lower(what) || ' | ' || TO_CHAR(next_date, 'HH24:MI') || ' |' line
  FROM user_jobs

aktive Jobs ermitteln


SELECT j.sid,
s.spid,
s.serial#,
j.log_user,
j.job,
j.broken,
j.failures,
j.last_date||':'||j.last_sec last_date,
j.this_date||':'||j.this_sec this_date,
j.next_date||':'||j.next_sec next_date,
j.next_date - j.last_date INTERVAL,
j.what
FROM (SELECT djr.SID, 
dj.LOG_USER, dj.JOB, dj.BROKEN, dj.FAILURES, 
dj.LAST_DATE, dj.LAST_SEC, dj.THIS_DATE, dj.THIS_SEC, 
dj.NEXT_DATE, dj.NEXT_SEC, dj.INTERVAL, dj.WHAT
FROM dba_jobs dj, dba_jobs_running djr
WHERE dj.job = djr.job ) j,
(SELECT p.spid, s.sid, s.serial#
FROM v$process p, v$session s
WHERE p.addr = s.paddr ) s
WHERE j.sid = s.sid;

siehe: http://blogs.ittoolbox.com/database/solutions/archives/killing-the-oracle-dbms_job-6498

-- Main.vermeul - 29 May 2006

Topic revision: r15 - 2010-02-10 - vermeul
 
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2017 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback