#=======================================================================
# Writer
: Lokanadham
Thandlam
#=======================================================================
--Example 11–1 Setting Value of
PLSQL_WARNINGS Compilation Parameter
FOR THE SESSION, ENABLE
ALL warnings—highly recommended during
development:
ALTER
SESSION SET PLSQL_WARNINGS='ENABLE:ALL';
FOR THE SESSION, ENABLE
PERFORMANCE warnings:
ALTER
SESSION SET PLSQL_WARNINGS='ENABLE:PERFORMANCE';
--For the procedure loc_var, enable
PERFORMANCE warnings, and reuse settings:
ALTER
PROCEDURE loc_var;
COMPILE
PLSQL_WARNINGS='ENABLE:PERFORMANCE';
REUSE
SETTINGS;
--For the session, enable SEVERE
warnings, disable PERFORMANCE warnings, and treat PLW-06002 warnings as errors:
ALTER
SESSION;
SET PLSQL_WARNINGS='ENABLE:SEVERE', 'DISABLE:PERFORMANCE', 'ERROR:06002';
FOR THE SESSION, DISABLE
ALL warnings:
ALTER
SESSION SET PLSQL_WARNINGS='DISABLE:ALL';
--Example 11–2 Displaying and Setting
PLSQL_WARNINGS with DBMS_WARNING Subprograms
DISABLE
ALL WARNING messages FOR this SESSION:
ALTER
SESSION SET PLSQL_WARNINGS='DISABLE:ALL';
--With warnings disabled, this procedure
compiles with no warnings:
CREATE
OR REPLACE
PROCEDURE unreachable_code
AUTHID DEFINER
AS
x CONSTANT
BOOLEAN := TRUE;
BEGIN
IF x
THEN
DBMS_OUTPUT.PUT_LINE
('TRUE');
ELSE
DBMS_OUTPUT.PUT_LINE
('FALSE');
END IF;
END unreachable_code;
/
--Enable all warning messages for this
session:
CALL DBMS_WARNING.set_warning_setting_string
('ENABLE:ALL', 'SESSION');
CHECK
WARNING setting:
SELECT
DBMS_WARNING.get_warning_setting_string () FROM DUAL;
--Recompile procedure:
ALTER
PROCEDURE unreachable_code COMPILE;
--Show errors:
SHOW ERRORS
--Example 11–3 Single Exception Handler
for Multiple Exceptions
CREATE
OR REPLACE
PROCEDURE select_item (t_column VARCHAR2, t_name VARCHAR2)
AUTHID DEFINER
IS
temp VARCHAR2
(30);
BEGIN
temp := t_column; -- For error message if next SELECT fails
-- Fails if table t_name does not have
column t_column:
SELECT COLUMN_NAME
INTO temp
FROM USER_TAB_COLS
WHERE TABLE_NAME = UPPER (t_name) AND COLUMN_NAME = UPPER (t_column);
temp := t_name; -- For error message if next SELECT fails
-- Fails if there is no table named
t_name:
SELECT OBJECT_NAME
INTO temp
FROM USER_OBJECTS
WHERE OBJECT_NAME = UPPER (t_name) AND OBJECT_TYPE = 'TABLE';
EXCEPTION
WHEN NO_DATA_FOUND
THEN
DBMS_OUTPUT.PUT_LINE
('No Data found for SELECT on ' || temp);
WHEN OTHERS
THEN
DBMS_OUTPUT.PUT_LINE
('Unexpected error');
RAISE;
END;
/
--Invoke procedure (there is a
DEPARTMENTS table, but it does not have a LAST_NAME column):
BEGIN
select_item ('departments', 'last_name');
END;
/
--Invoke procedure (there is no EMP
table):
BEGIN
select_item ('emp', 'last_name');
END;
/
--Example 11–4 Locator Variables for
Statements that Share Exception Handler
CREATE
OR REPLACE
PROCEDURE loc_var
AUTHID DEFINER
IS
stmt_no POSITIVE;
name_ VARCHAR2
(100);
BEGIN
stmt_no := 1;
SELECT table_name
INTO name_
FROM user_tables
WHERE table_name LIKE 'ABC%';
stmt_no := 2;
SELECT table_name
INTO name_
FROM user_tables
WHERE table_name LIKE 'XYZ%';
EXCEPTION
WHEN NO_DATA_FOUND
THEN
DBMS_OUTPUT.PUT_LINE
('Table name not found in query ' || stmt_no);
END;
/
CALL loc_var ();
--Example 11–5 Naming Internally Defined
Exception
DECLARE
deadlock_detected EXCEPTION;
PRAGMA
EXCEPTION_INIT(deadlock_detected, -60);
BEGIN
...
EXCEPTION
WHEN deadlock_detected THEN
...
END;
/
--Example 11–6 Anonymous Block Handles
ZERO_DIVIDE
DECLARE
stock_price NUMBER
:= 9.73;
net_earnings NUMBER
:= 0;
pe_ratio NUMBER;
BEGIN
pe_ratio := stock_price / net_earnings; -- raises ZERO_DIVIDE exception
DBMS_OUTPUT.PUT_LINE
('Price/earnings ratio = ' || pe_ratio);
EXCEPTION
WHEN ZERO_DIVIDE
THEN
DBMS_OUTPUT.PUT_LINE
('Company had zero earnings.');
pe_ratio := NULL;
END;
/
--Example 11–7 Anonymous Block Avoids
ZERO_DIVIDE
DECLARE
stock_price NUMBER
:= 9.73;
net_earnings NUMBER
:= 0;
pe_ratio NUMBER;
BEGIN
pe_ratio :=
CASE net_earnings WHEN 0 THEN NULL ELSE stock_price / net_earnings END;
END;
/
--Example 11–8 Anonymous Block Handles
ROWTYPE_MISMATCH
CREATE
OR REPLACE
PACKAGE emp_dept_data
AUTHID DEFINER
AS
TYPE cv_type IS REF CURSOR;
PROCEDURE open_cv (CV IN OUT cv_type, discrim IN POSITIVE);
END emp_dept_data;
/
CREATE
OR REPLACE
PACKAGE BODY emp_dept_data
AS
PROCEDURE open_cv (CV IN OUT cv_type, discrim IN POSITIVE)
IS
BEGIN
IF discrim = 1
THEN
OPEN CV FOR
SELECT *
FROM EMPLOYEES
ORDER BY employee_id;
ELSIF discrim = 2
THEN
OPEN CV FOR
SELECT *
FROM DEPARTMENTS
ORDER BY department_id;
END IF;
END open_cv;
END emp_dept_data;
/
--Invoke procedure open_cv from anonymous
block:
DECLARE
emp_rec EMPLOYEES%ROWTYPE;
dept_rec DEPARTMENTS%ROWTYPE;
CV
Emp_dept_data.CV_TYPE;
BEGIN
emp_dept_data.open_cv (CV, 1); -- Open cv for EMPLOYEES fetch.
FETCH CV INTO dept_rec;
-- Fetch from DEPARTMENTS.
DBMS_OUTPUT.PUT
(dept_rec.DEPARTMENT_ID);
DBMS_OUTPUT.PUT_LINE
(' ' || dept_rec.LOCATION_ID);
EXCEPTION
WHEN ROWTYPE_MISMATCH
THEN
BEGIN
DBMS_OUTPUT.PUT_LINE
(
'Row type mismatch, fetching EMPLOYEES
data ...');
FETCH CV INTO emp_rec;
DBMS_OUTPUT.PUT
(emp_rec.DEPARTMENT_ID);
DBMS_OUTPUT.PUT_LINE
(' ' || emp_rec.LAST_NAME);
END;
END;
/
--
--Example 11–9 Redeclared Predefined
Identifier
DROP TABLE t;
CREATE
TABLE t (c NUMBER);
--In the following block, the INSERT
statement implicitly raises the predefined exception INVALID_NUMBER, which the
exception handler handles.
DECLARE
default_number NUMBER := 0;
BEGIN
INSERT INTO t
VALUES (TO_NUMBER ('100.00', '9G999'));
EXCEPTION
WHEN INVALID_NUMBER
THEN
DBMS_OUTPUT.PUT_LINE
('Substituting default value for invalid
number.');
INSERT INTO t
VALUES (default_number);
END;
/
--The following block redeclares the
predefined exception INVALID_NUMBER. When the INSERT statement implicitly
raises the predefined exception INVALID_NUMBER, the exception handler does not
handle it.
DECLARE
default_number NUMBER := 0;
i NUMBER
:= 5;
INVALID_NUMBER EXCEPTION; -- redeclare predefined exception
BEGIN
INSERT INTO t
VALUES (TO_NUMBER ('100.00', '9G999'));
EXCEPTION
WHEN INVALID_NUMBER
THEN
DBMS_OUTPUT.PUT_LINE
('Substituting default value for invalid
number.');
INSERT INTO t
VALUES (default_number);
END;
/
--The exception handler in the preceding
block handles the predefined exception INVALID_NUMBER if you qualify the
exception name in the exception handler:
DECLARE
default_number NUMBER := 0;
i NUMBER
:= 5;
INVALID_NUMBER EXCEPTION; -- redeclare predefined exception
BEGIN
INSERT INTO t
VALUES (TO_NUMBER ('100.00', '9G999'));
EXCEPTION
WHEN STANDARD.INVALID_NUMBER
THEN
DBMS_OUTPUT.PUT_LINE
('Substituting default value for invalid
number.');
INSERT INTO t
VALUES (default_number);
END;
/
--Example 11–10 Declaring, Raising, and
Handling User-Defined Exception
CREATE
PROCEDURE account_status (due_date DATE, today DATE)
AUTHID DEFINER
IS
past_due EXCEPTION; -- declare exception
BEGIN
IF due_date < today
THEN
RAISE past_due; -- explicitly raise exception
END IF;
EXCEPTION
WHEN past_due
THEN -- handle exception
DBMS_OUTPUT.PUT_LINE
('Account past due.');
END;
/
BEGIN
account_status (TO_DATE ('01-JUL-2010', 'DD-MON-YYYY'),
TO_DATE ('09-JUL-2010', 'DD-MON-YYYY'));
END;
/
--Example 11–11 Explicitly Raising
Predefined Exception
DROP TABLE t;
CREATE
TABLE t (c NUMBER);
CREATE
PROCEDURE p (n NUMBER)
AUTHID DEFINER
IS
default_number NUMBER := 0;
BEGIN
IF n < 0
THEN
RAISE INVALID_NUMBER; -- raise explicitly
ELSE
INSERT INTO t
VALUES (TO_NUMBER ('100.00', '9G999')); -- raise implicitly
END IF;
EXCEPTION
WHEN INVALID_NUMBER
THEN
DBMS_OUTPUT.PUT_LINE
('Substituting default value for invalid
number.');
INSERT INTO t
VALUES (default_number);
END;
/
BEGIN
p (-1);
END;
/
BEGIN
p (1);
END;
/
--Example 11–12 Reraising Exception
DECLARE
salary_too_high EXCEPTION;
current_salary NUMBER := 20000;
max_salary NUMBER
:= 10000;
erroneous_salary NUMBER;
BEGIN
BEGIN
IF current_salary > max_salary
THEN
RAISE salary_too_high; -- raise exception
END IF;
EXCEPTION
WHEN salary_too_high
THEN -- start handling exception
erroneous_salary := current_salary;
DBMS_OUTPUT.PUT_LINE
(
'Salary ' || erroneous_salary || ' is out of range.');
DBMS_OUTPUT.PUT_LINE
('Maximum salary is ' || max_salary || '.');
RAISE; -- reraise current exception (exception
name is optional)
END;
EXCEPTION
WHEN salary_too_high
THEN -- finish handling exception
current_salary
:= max_salary;
DBMS_OUTPUT.PUT_LINE
(
'Revising salary from '
||
erroneous_salary
|| ' to '
||
current_salary
|| '.');
END;
/
--Example 11–13 Raising User-Defined
Exception with RAISE_APPLICATION_ERROR
CREATE
PROCEDURE account_status (due_date DATE, today DATE)
AUTHID DEFINER
IS
BEGIN
IF due_date < today
THEN -- explicitly raise exception
RAISE_APPLICATION_ERROR (-20000, 'Account past due.');
END IF;
END;
/
DECLARE
past_due EXCEPTION; -- declare exception
PRAGMA EXCEPTION_INIT (past_due, -20000); -- assign error code to exception
BEGIN
account_status (TO_DATE ('01-JUL-2010', 'DD-MON-YYYY'),
TO_DATE ('09-JUL-2010', 'DD-MON-YYYY')); -- invoke procedure
EXCEPTION
WHEN past_due
THEN
-- handle exception
DBMS_OUTPUT.PUT_LINE
(TO_CHAR (SQLERRM
(-20000)));
END;
/


