19. prosince 2018

Problém v databázi Oracle s plánovaným časem v dbms_scheduller po přechodu z dbms_job


Dbms_job pracuje s plánovaným časem v datovém typu DATE, zatímco dbms_scheduller používá TIMESTAMP WITH TIME ZONE.
Dbms_job vypočítává plánovaný čas spuštění jobu PL/SQL výrazem například to_date(to_char(sysdate+1,'dd.mm.yyyy')||' 02:30','dd.mm.yyyy hh24:mi') tj.následující den ve 2:30 . Dbms_scheduller umožňuje použít jak PL/SQL výraz tak nově tzv. kalendářovou syntaxi, například FREQ=DAILY; BYHOUR=2; BYMINUTE=30 tj. každý den ve 2:30. Podrobněji o kalendářové syntaxi viz https://docs.oracle.com/database/121/ARPLS/d_sched.htm#ARPLS73835.

Problém je, pokud se použijí původní PL/SQL výrazy, které vracely hodnotu datového typu DATE, jako PL/SQL výrazy pro joby dbms_scheduller, které očekávají TIMESTAMP WITH TIME ZONE. Při implicitní konverzi z DATE na TIMESTAMP WITH TIME ZONE  může dojít k vytvoření času, který v daném časovém pásmu neexistuje, což v naší časové zóně je úsek v intervalu 2:00 a 3:00 při přechodu mezi středoevropským a letním časem.
Důsledkem naplánování do neexistujícího času je zastavení jobu. Job je ve stavu BROKEN.
Možné řešení je přepsání plánovacího výrazu do kalendářové syntaxe nebo na PL/SQL výraz, který vrátí regulérní čas v datovém typu TIMESTAMP WITH TIME ZONE například to_timestamp_tz(to_char(current_timestamp+interval '1' day,'DD.MM.YYYY TZR')||' 02:30','DD.MM.YYYY TZR HH24:MI').

Autor článku: Pavel Turek

Žádné komentáře:

Okomentovat