plsql
Behandeling van uitzonderingen
Zoeken…
Invoering
Oracle produceert verschillende uitzonderingen. Het zal je misschien verbazen hoe vervelend het kan zijn om je code te laten stoppen met een onduidelijk bericht. Om het vermogen van uw PL / SQL-code om gemakkelijk te repareren te verbeteren, is het noodzakelijk om uitzonderingen op het laagste niveau af te handelen. Verberg nooit een uitzondering "onder het tapijt", tenzij u hier bent om uw stukje code alleen voor u te bewaren en voor niemand anders te onderhouden.
Behandeling van uitzonderingen op verbindingsfouten
Elke standaard Oracle-fout is gekoppeld aan een foutnummer. Het is belangrijk om te anticiperen op wat er mis kan gaan in uw code. Hier voor een verbinding met een andere database kan dit zijn:
-
-28000
account is vergrendeld -
-28001
wachtwoord verlopen -
-28002
respijtperiode -
-1017
verkeerde gebruiker / wachtwoord
Hier is een manier om te testen wat er misgaat met de gebruiker die door de databasekoppeling wordt gebruikt:
declare
v_dummy number;
begin
-- testing db link
execute immediate 'select COUNT(1) from [email protected]' into v_dummy ;
-- if we get here, exception wasn't raised: display COUNT's result
dbms_output.put_line(v_dummy||' users on PASS db');
EXCEPTION
-- exception can be referred by their name in the predefined Oracle's list
When LOGIN_DENIED
then
dbms_output.put_line('ORA-1017 / USERNAME OR PASSWORD INVALID, TRY AGAIN');
When Others
then
-- or referred by their number: stored automatically in reserved variable SQLCODE
If SQLCODE = '-2019'
Then
dbms_output.put_line('ORA-2019 / Invalid db_link name');
Elsif SQLCODE = '-1035'
Then
dbms_output.put_line('ORA-1035 / DATABASE IS ON RESTRICTED SESSION, CONTACT YOUR DBA');
Elsif SQLCODE = '-28000'
Then
dbms_output.put_line('ORA-28000 / ACCOUNT IS LOCKED. CONTACT YOUR DBA');
Elsif SQLCODE = '-28001'
Then
dbms_output.put_line('ORA-28001 / PASSWORD EXPIRED. CONTACT YOUR DBA FOR CHANGE');
Elsif SQLCODE = '-28002'
Then
dbms_output.put_line('ORA-28002 / PASSWORD IS EXPIRED, CHANGED IT');
Else
-- and if it's not one of the exception you expected
dbms_output.put_line('Exception not specifically handled');
dbms_output.put_line('Oracle Said'||SQLCODE||':'||SQLERRM);
End if;
END;
/
Definieer aangepaste uitzondering, verhoog het en kijk waar het vandaan komt
Om dit te illustreren, hier is een functie die 3 verschillende "verkeerde" gedragingen heeft
- parameter is helemaal dom: we gebruiken een door de gebruiker gedefinieerde uitdrukking
- parameter heeft een typefout: we gebruiken de standaardfout
NO_DATA_FOUND
Oracle - een andere, maar niet afgehandelde zaak
Pas het aan uw normen aan:
DECLARE
this_is_not_acceptable EXCEPTION;
PRAGMA EXCEPTION_INIT(this_is_not_acceptable, -20077);
g_err varchar2 (200) := 'to-be-defined';
w_schema all_tables.OWNER%Type;
PROCEDURE get_schema( p_table in Varchar2, p_schema out Varchar2)
Is
w_err varchar2 (200) := 'to-be-defined';
BEGIN
w_err := 'get_schema-step-1:';
If (p_table = 'Delivery-Manager-Is-Silly') Then
raise this_is_not_acceptable;
end if;
w_err := 'get_schema-step-2:';
Select owner Into p_schema
From all_tables
where table_name like(p_table||'%');
EXCEPTION
WHEN NO_DATA_FOUND THEN
-- handle Oracle-defined exception
dbms_output.put_line('[WARN]'||w_err||'This can happen. Check the table name you entered.');
WHEN this_is_not_acceptable THEN
-- handle your custom error
dbms_output.put_line('[WARN]'||w_err||'Please don''t make fun of the delivery manager.');
When others then
dbms_output.put_line('[ERR]'||w_err||'unhandled exception:'||sqlerrm);
raise;
END Get_schema;
BEGIN
g_err := 'Global; first call:';
get_schema('Delivery-Manager-Is-Silly', w_schema);
g_err := 'Global; second call:';
get_schema('AAA', w_schema);
g_err := 'Global; third call:';
get_schema('', w_schema);
g_err := 'Global; 4th call:';
get_schema('Can''t reach this point due to previous error.', w_schema);
EXCEPTION
When others then
dbms_output.put_line('[ERR]'||g_err||'unhandled exception:'||sqlerrm);
-- you may raise this again to the caller if error log isn't enough.
-- raise;
END;
/
Geven op een regelmatige database:
[WARN]get_schema-step-1:Please don't make fun of the delivery manager.
[WARN]get_schema-step-2:This can happen. Check the table name you entered.
[ERR]get_schema-step-2:unhandled exception:ORA-01422: exact fetch returns more than requested number of rows
[ERR]Global; third call:unhandled exception:ORA-01422: exact fetch returns more than requested number of rows
Vergeet niet dat uitzonderingen hier zijn om zeldzame gevallen te behandelen. Ik zag applicaties die bij elke toegang een uitzondering opriepen, gewoon om om een gebruikerswachtwoord te vragen en zeiden "niet verbonden" ... zoveel computerverspilling.