Tag Archives: Oracle

Sommer-/Winterzeit und Oracle DBMS_SCHEDULER

Ende März hatte ich ein Projekt gehabt, bei dem auch ein Schedulerjob angelegt werden musste. Der Job sollte von Montag bis Freitag um 8 Uhr morgens starten und zum letzten mal um 18 Uhr gestartet werden. Dabei sollte der Job automatisch gestartet werden, falls die DB mal runtergefahren werden sollte
So legte ich den Job an:

BEGIN
dbms_scheduler.create_job ( job_name => 'MY_JOB'
, job_type => 'STORED_PROCEDURE'
, job_action => 'SCOTT.MY_JOB'
, start_date => SYSDATE
, repeat_interval => 'freq=SECONDLY; byday=MON,TUE,WED,THU,FRI; BYHOUR=8,9,10,11,12,13,14,15,16,17,18'
, end_date => NULL
, enabled => TRUE
, comments => 'Job to test the effect of time zone.'
);
END;
/

Soweit war alles gut, der Job startete zu der gewünschten Zeit, bis die Zeitumstellung am 31. März kam. Als ich dann den Job am 1. April überprüfte stellte ich fest, dass der Job nicht wie gewünscht um 8 Uhr gestartet hat.
Die Abfrage auf der user_scheduler_jobs View ergab folgende Information

SQL> SELECT
           job_name
          ,start_date
          ,next_run_date
    FROM user_scheduler_jobs
    WHERE job_name ='MY_JOB';
 
JOB_NAME           START_DATE                  NEXT_RUN_DATE
------------------ ----------------------------------- ------------------------------------
MY_JOB 20-MAR-12 23.30.10.154755 AM +02:00  1-APR-12 08.00.00.685030 AM +02:00

Der Job sollte um 8 Uhr morgens gestartet werden jedoch in der Zeitzone +02:00. Nach der Zeitumstellung wurde die Zeitzone nicht aktualisiert und somit wurde starte der Job eine Stunde später.
Eine kleine recherche im Internet ergab, dass die Jobs solcher Art mit einer explizieten angabe der Timezone angelegt werden sollten

BEGIN
  dbms_scheduler.drop_job('MY_JOB');
END;
/
 
PL/SQL PROCEDURE successfully completed.
 
SQL> BEGIN
        dbms_scheduler.create_job ( job_name => 'MY_JOB'
        , job_type => 'STORED_PROCEDURE'
        , job_action => 'SCOTT.MY_JOB'
        , start_date => systimestamp at TIME zone 'EUROPE/BERLIN', -- Unterschied liegt hier
        , repeat_interval => 'freq=SECONDLY; byday=MON,TUE,WED,THU,FRI; BYHOUR=8,9,10,11,12,13,14,15,16,17,18'
        , end_date => NULL
        , enabled => TRUE
        , comments => 'Job to test the effect of time zone.'
        );
    END;
    /

So wir der Scheduler Job auch mit der Zeitumstellung zurecht kommen. Und würde auch nach der weiteren Umstellung auf Winterzeit um 8 Uhr starten.

weitere Informationen zu Scheduler Jobs in Oracle:
* Job-Steuerung in Oracle Datenbanken
* Scheduler (DBMS_SCHEDULER) Enhancements in Oracle Database 11g Release 2
* Oracle 11.1 Doku- Scheduler Jobs

Unit Test für Object Types in SQLDeveloper

SqlDeveloper ist eine kostenlose IDE von Oracle für SQL und PL/SQL Entwicklung, sowie Verwaltung der Datenbank. Mitlerweile befindet es sich in der Version 3.0. Leider gibt es in der Version immer noch keine Unterstützung der Unittests für object types. Dies ist ein sehr wichtiges Feature, wer in Oracle objektorientiert programmiert und somit sehr oft Types verwendet.
Dieses Feature wurde bei Oracle angefordert und für Release 3.0 eingeplant, doch bis jetzt ist noch nichts passiert. Bitte Voted für das Feature, damit es auch realisiert wird und der Entwicklung.
Zum Feature request
wiki über SqlDeveloper
Download SqlDeveloper 3.0

PL/SQL Challenge vom 31.03.2011

Es war eine super Frage von Jeff Kemp in dem gestrigen PL/SQL Challenge. Die Frage war kurz und verständlich und zwar
was kommt raus?

DECLARE
   d1   DATE := TO_DATE ('09/2011', 'MM/YYYY');
   d2   DATE := TO_DATE ('10/2011', 'MM/YYYY');
   v1   VARCHAR2 (10);
   v2   VARCHAR2 (10);
BEGIN
   v1 := TO_CHAR (d1, 'Month');
   v2 := TO_CHAR (d2, 'Month');

   DBMS_OUTPUT.put_line (
      CASE
         WHEN v1 = 'Sep' AND v2 = 'Oct' THEN 'Short and Sweet'
         WHEN v1 = 'September' AND v2 = 'October' THEN 'Long and Sour'
         ELSE 'Not Short and Not Long'
      END);
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.put_line ('Something else entirely');
END;

Auf den ersten Blick sieht der Code recht simpel aus, so dachten ich mit den Arbeitskollegen auch. Ohne das ganze auszuprobieren, wusste ich, dass TO_CHAR (d1, ‘Month’); den vollen Monatsnamen zurückgibt. So war die Variante mit ‘Short and Sweet’ ganz klar ausgeschlossen. Da wir aber eine deutsche Session benutzen, würden wir statt, October, Oktober zurückbekommen.
So habe ich mir überlegt, wenn der Autor nicht erwähnt hat, dass es explizit die englische Session sein müsste, wird ein rerank geben.
Mit Kollegen haben wir zuerst auch nur das Session Problem ausdiskutiert, und haben auf rerank gehoft.
Der Hacken war aber woanders, nämlich wird beim Format ‘month’ in der to_char Funktion, der String auf die Länge 9 gepadded im oberen Beispiel, und somit scheitert beim Vergleich von v2 = ‘October’, da v2 := ‘October ‘ und somit in dem ELSE Zweig landet.

Echt erstaunlich, was es für Kleinigkeiten in einer Sprache geben kann, die man nicht kennt, und evnt. später nicht beachtet.