Oracle PL/SQL Tutorial/PL SQL Programming/User Defined Exceptions
Содержание
Adding User-Defined Exceptions
Before raising a user-defined exception, you must first declare the exception.
The syntax is
<source lang="sql">
<exception_name> exception;</source>
A User-Defined Exception
<source lang="sql">
SQL> SQL> SQL> -- create demo table SQL> create table Employee(
2 ID VARCHAR2(4 BYTE) NOT NULL, 3 First_Name VARCHAR2(10 BYTE), 4 Last_Name VARCHAR2(10 BYTE), 5 Start_Date DATE, 6 End_Date DATE, 7 Salary Number(8,2), 8 City VARCHAR2(10 BYTE), 9 Description VARCHAR2(15 BYTE) 10 ) 11 /
Table created. SQL> SQL> -- prepare data SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
2 values ("01","Jason", "Martin", to_date("19960725","YYYYMMDD"), to_date("20060725","YYYYMMDD"), 1234.56, "Toronto", "Programmer") 3 /
1 row created. SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
2 values("02","Alison", "Mathews", to_date("19760321","YYYYMMDD"), to_date("19860221","YYYYMMDD"), 6661.78, "Vancouver","Tester") 3 /
1 row created. SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
2 values("03","James", "Smith", to_date("19781212","YYYYMMDD"), to_date("19900315","YYYYMMDD"), 6544.78, "Vancouver","Tester") 3 /
1 row created. SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
2 values("04","Celia", "Rice", to_date("19821024","YYYYMMDD"), to_date("19990421","YYYYMMDD"), 2344.78, "Vancouver","Manager") 3 /
1 row created. SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
2 values("05","Robert", "Black", to_date("19840115","YYYYMMDD"), to_date("19980808","YYYYMMDD"), 2334.78, "Vancouver","Tester") 3 /
1 row created. SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
2 values("06","Linda", "Green", to_date("19870730","YYYYMMDD"), to_date("19960104","YYYYMMDD"), 4322.78,"New York", "Tester") 3 /
1 row created. SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
2 values("07","David", "Larry", to_date("19901231","YYYYMMDD"), to_date("19980212","YYYYMMDD"), 7897.78,"New York", "Manager") 3 /
1 row created. SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
2 values("08","James", "Cat", to_date("19960917","YYYYMMDD"), to_date("20020415","YYYYMMDD"), 1232.78,"Vancouver", "Tester") 3 /
1 row created. SQL> SQL> SQL> SQL> -- display data in the table SQL> select * from Employee
2 /
ID FIRST_NAME LAST_NAME START_DAT END_DATE SALARY CITY DESCRIPTION
-------------------- -------------------- --------- --------- ---------- ---------- ---------------
01 Jason Martin 25-JUL-96 25-JUL-06 1234.56 Toronto Programmer 02 Alison Mathews 21-MAR-76 21-FEB-86 6661.78 Vancouver Tester 03 James Smith 12-DEC-78 15-MAR-90 6544.78 Vancouver Tester 04 Celia Rice 24-OCT-82 21-APR-99 2344.78 Vancouver Manager 05 Robert Black 15-JAN-84 08-AUG-98 2334.78 Vancouver Tester 06 Linda Green 30-JUL-87 04-JAN-96 4322.78 New York Tester 07 David Larry 31-DEC-90 12-FEB-98 7897.78 New York Manager 08 James Cat 17-SEP-96 15-APR-02 1232.78 Vancouver Tester 8 rows selected. SQL> SQL> SQL> SQL> create or replace function f_ValidateSalary(i_empNo VARCHAR, i_new_Sal NUMBER)
2 return VARCHAR2 3 is 4 v_current_Sal NUMBER; 5 e_increaseTooLarge exception; 6 begin 7 select salary into v_current_Sal 8 from employee 9 where id=i_empNo; 10 11 if (i_new_Sal/v_current_Sal) * 100 > 300 then 12 raise e_increaseTooLarge; 13 end if; 14 15 return "Y"; 16 exception 17 when e_increaseTooLarge then 18 DBMS_OUTPUT.put_line("increaseTooLarge"); 19 return "N"; 20 end; 21 /
Function created. SQL> SQL> SQL> select f_ValidateSalary("01", 10000) from dual; F_VALIDATESALARY("01",10000)
N increaseTooLarge SQL> SQL> SQL> -- clean the table SQL> drop table Employee
2 /
Table dropped. SQL> SQL></source>
Including error messages in user-defined exceptions
<source lang="sql">
SQL> SQL> SQL> SQL> -- create demo table SQL> create table Employee(
2 ID VARCHAR2(4 BYTE) NOT NULL, 3 First_Name VARCHAR2(10 BYTE), 4 Last_Name VARCHAR2(10 BYTE), 5 Start_Date DATE, 6 End_Date DATE, 7 Salary Number(8,2), 8 City VARCHAR2(10 BYTE), 9 Description VARCHAR2(15 BYTE) 10 ) 11 /
Table created. SQL> SQL> -- prepare data SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
2 values ("01","Jason", "Martin", to_date("19960725","YYYYMMDD"), to_date("20060725","YYYYMMDD"), 1234.56, "Toronto", "Programmer") 3 /
1 row created. SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
2 values("02","Alison", "Mathews", to_date("19760321","YYYYMMDD"), to_date("19860221","YYYYMMDD"), 6661.78, "Vancouver","Tester") 3 /
1 row created. SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
2 values("03","James", "Smith", to_date("19781212","YYYYMMDD"), to_date("19900315","YYYYMMDD"), 6544.78, "Vancouver","Tester") 3 /
1 row created. SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
2 values("04","Celia", "Rice", to_date("19821024","YYYYMMDD"), to_date("19990421","YYYYMMDD"), 2344.78, "Vancouver","Manager") 3 /
1 row created. SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
2 values("05","Robert", "Black", to_date("19840115","YYYYMMDD"), to_date("19980808","YYYYMMDD"), 2334.78, "Vancouver","Tester") 3 /
1 row created. SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
2 values("06","Linda", "Green", to_date("19870730","YYYYMMDD"), to_date("19960104","YYYYMMDD"), 4322.78,"New York", "Tester") 3 /
1 row created. SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
2 values("07","David", "Larry", to_date("19901231","YYYYMMDD"), to_date("19980212","YYYYMMDD"), 7897.78,"New York", "Manager") 3 /
1 row created. SQL> insert into Employee(ID, First_Name, Last_Name, Start_Date, End_Date, Salary, City, Description)
2 values("08","James", "Cat", to_date("19960917","YYYYMMDD"), to_date("20020415","YYYYMMDD"), 1232.78,"Vancouver", "Tester") 3 /
1 row created. SQL> SQL> SQL> SQL> -- display data in the table SQL> select * from Employee
2 /
ID FIRST_NAME LAST_NAME START_DAT END_DATE SALARY CITY DESCRIPTION
-------------------- -------------------- --------- --------- ---------- ---------- ---------------
01 Jason Martin 25-JUL-96 25-JUL-06 1234.56 Toronto Programmer 02 Alison Mathews 21-MAR-76 21-FEB-86 6661.78 Vancouver Tester 03 James Smith 12-DEC-78 15-MAR-90 6544.78 Vancouver Tester 04 Celia Rice 24-OCT-82 21-APR-99 2344.78 Vancouver Manager 05 Robert Black 15-JAN-84 08-AUG-98 2334.78 Vancouver Tester 06 Linda Green 30-JUL-87 04-JAN-96 4322.78 New York Tester 07 David Larry 31-DEC-90 12-FEB-98 7897.78 New York Manager 08 James Cat 17-SEP-96 15-APR-02 1232.78 Vancouver Tester 8 rows selected. SQL> SQL> SQL> SQL> create or replace procedure p_validateSalary(i_empNo VARCHAR, i_new_sal NUMBER)
2 is 3 v_current_sal Number(8,2); 4 e_increaseTooLarge EXCEPTION; 5 pragma exception_init (e_increaseTooLarge, -20999); 6 begin 7 select salary into v_current_sal 8 from employee 9 where id=i_empNo; 10 if (i_new_sal/v_current_sal)*100>300 11 then 12 raise_application_error (-20999, "Cannot triple salary for employee #"||i_empNo); 13 end if; 14 exception 15 when e_increaseTooLarge then 16 DBMS_OUTPUT.put_line("increaseTooLarge"); 17 raise; 18 end; 19 /
Procedure created. SQL> SQL> call p_validateSalary("01", 10000); increaseTooLarge call p_validateSalary("01", 10000)
*
ERROR at line 1: ORA-20999: Cannot triple salary for employee #01 ORA-06512: at "sqle.P_VALIDATESALARY", line 17
SQL> SQL> -- clean the table SQL> drop table Employee
2 /
Table dropped. SQL> SQL></source>
Propagation of Exceptions between Program Units
<source lang="sql">
SQL> SQL> create or replace function f_makeAddress (i_address VARCHAR2,i_city VARCHAR2,i_state VARCHAR2,i_zip VARCHAR2)
2 return VARCHAR2 3 is 4 e_badZip EXCEPTION; 5 pragma EXCEPTION_init(e_badZip,-20998); 6 v_out VARCHAR2(256); 7 begin 8 p_validateZip (i_zip); 9 v_out:= i_address||", "||i_city ||", "||i_state ||", "||i_zip; 10 return v_out; 11 exception 12 when e_badZip then 13 return i_zip || ": Invalid zip code."; 14 end; 15 /
Function created. SQL> SQL> create or replace procedure p_validateZip (i_zipCode VARCHAR2)
2 is 3 e_tooShort EXCEPTION; 4 e_tooLong EXCEPTION; 5 e_badZip EXCEPTION; 6 pragma exception_init(e_badZip, -20998); 7 v_tempZip NUMBER; 8 Begin 9 if length(i_zipCode)< 5 then 10 Raise e_tooShort; 11 elsif length(i_zipCode)> 6 then 12 Raise e_tooLong; 13 end if; 14 15 v_tempZip := to_number(i_zipCode); 16 17 exception 18 when e_tooLong then 19 DBMS_OUTPUT.put_line("long zip"); 20 raise e_badZip; 21 when e_tooShort then 22 DBMS_OUTPUT.put_line("short zip"); 23 -- raise e_badZip SHOULD be here 24 when value_error then 25 DBMS_OUTPUT.put_line("non-numeric zip"); 26 raise; -- re-raising the same exception 27 end; 28 /
Procedure created. SQL> --Scenario 1: No rule violations SQL> SQL> declare
2 v_out VARCHAR2(2000); 3 begin 4 v_out:=f_makeAddress("AA","City","CA","94061"); 5 DBMS_OUTPUT.put_line(v_out); 6 end; 7 /
AA, City, CA, 94061 PL/SQL procedure successfully completed. SQL> SQL> SQL> --Scenario 2: Short ZIP code SQL> SQL> SQL> declare
2 v_out VARCHAR2(2000); 3 begin 4 v_out:=f_makeAddress("A","City", "CA","940"); 5 DBMS_OUTPUT.put_line(v_out); 6 end; 7 /
short zip A, City, CA, 940 PL/SQL procedure successfully completed. SQL> --Scenario 3: Non-numeric ZIP code SQL> SQL> declare
2 v_out VARCHAR2(2000); 3 begin 4 v_out:=f_makeAddress("A","City" , "CA","9406A"); 5 DBMS_OUTPUT.put_line(v_out); 6 end; 7 /
non-numeric zip declare
ERROR at line 1: ORA-06502: PL/SQL: numeric or value error: character to number conversion error ORA-06512: at "sqle.P_VALIDATEZIP", line 26 ORA-06512: at "sqle.F_MAKEADDRESS", line 8 ORA-06512: at line 4
SQL> -- Long ZIP code SQL> SQL> declare
2 v_out VARCHAR2(2000); 3 begin 4 v_out:=f_makeAddress("A","City","CA","940612345"); 5 DBMS_OUTPUT.put_line(v_out); 6 end; 7 /
long zip 940612345: Invalid zip code. PL/SQL procedure successfully completed. SQL></source>