Istnieją dwa główne wzorce, które można zastosować do obsługi wyjątków; „patrz, zanim skoczysz” (LBYL) i „łatwiej prosić o wybaczenie niż o pozwolenie” (EAFP). LBYL zaleca sprawdzenie, czy zadanie istnieje, zanim spróbuje je porzucić. EAFP obejmuje próbę porzucenia zadania, a następnie przechwycenie i zignorowanie tego konkretnego błędu, jeśli wystąpi.
Jeśli miałbyś zastosować LBYL, możesz wysłać zapytanie do widoku systemowego USER_SCHEDULER_JOBS
aby sprawdzić, czy Twoja praca istnieje. Jeśli tak, upuść go.
declare
l_job_exists number;
begin
select count(*) into l_job_exists
from user_scheduler_jobs
where job_name = 'STATISTICS_COLUMNS_JOB'
;
if l_job_exists = 1 then
dbms_scheduler.drop_job(job_name => 'STATISTICS_COLUMNS_JOB');
end if;
end;
W przypadku EAFP jest nieco inaczej; zdefiniuj własny wyjątek przez nazywanie wewnętrznie zdefiniowanego wyjątku i tworzenie jego wystąpienia z kodem błędu, który chcesz przechwycić. Jeśli ten błąd zostanie następnie zgłoszony, nie rób nic.
declare
job_doesnt_exist EXCEPTION;
PRAGMA EXCEPTION_INIT( job_doesnt_exist, -27475 );
begin
dbms_scheduler.drop_job(job_name => 'STATISTICS_COLUMNS_JOB');
exception when job_doesnt_exist then
null;
end;
Warto zwrócić uwagę na dwie rzeczy dotyczące tej drugiej metody.
-
Jestem tylko przechwytywanie błędu wywołanego przez ten konkretny wyjątek. To samo można osiągnąć za pomocą
EXCEPTION WHEN OTHERS
ale gorąco polecam przeciw robiąc to.Jeśli obsługujesz wyjątek, powinieneś dokładnie wiedzieć, co z nim zrobisz. Jest mało prawdopodobne, że będziesz w stanie prawidłowo obsłużyć każdy wyjątek Oracle za pomocą
OTHERS
a jeśli to zrobisz, prawdopodobnie powinieneś je rejestrować w miejscu, w którym zostaną zauważone. Cytując Wytyczne dotyczące unikania i obsługi wyjątków : -
propagacja wyjątków działa od bloku wewnętrznego do bloku zewnętrznego, więc pierwotną przyczyną błędu będzie pierwszy wyjątek.