Det finns två huvudmönster du kan tillämpa på undantagshantering; "se innan du hoppar" (LBYL) och "det är lättare att be om förlåtelse än om tillåtelse" (EAFP). LBYL skulle förespråka att man kontrollerar om jobbet finns innan man försöker släppa det. EAFP skulle innebära ett försök att släppa jobbet och sedan fånga upp och ignorera det specifika felet, om det inträffar.
Om du skulle använda LBYL kan du fråga systemvyn USER_SCHEDULER_JOBS
för att se om ditt jobb finns. Om den gör det, släpp den.
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;
För EAFP är det något annorlunda; definiera ditt eget undantag genom att nämna ett internt definierat undantag och instansiera den med felkoden du vill fånga. Om det felet sedan uppstår, gör ingenting.
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;
Det är värt att notera två saker om denna andra metod.
-
Jag är endast fånga felet som detta specifika undantag uppstår. Det skulle vara möjligt att uppnå samma sak med
EXCEPTION WHEN OTHERS
men jag rekommenderar starkt emot gör detta.Om du hanterar ett undantag bör du veta exakt vad du ska göra med det. Det är osannolikt att du har förmågan att hantera varje enskilt Oracle-undantag korrekt med
OTHERS
och om du gör det borde du förmodligen logga dem någonstans där de kommer att märkas. För att citera från Oracles riktlinjer för att undvika och hantera undantag : -
Oracles förökning av undantag fungerar från internt block till externt block så den ursprungliga orsaken till felet blir det första undantaget.