Pl/Sql Exception

Exceptions

 

Oracle includes about 20 predefined exceptions (errors) – we can allow Oracle to raise these implicitly.

For errors that don’t fall into the predefined categories – declare in advance and allow oracle to raise an exception.

For problems that are not recognised as an error by Oracle – but still cause some difficulty within your application – declare a User Defined Error and raise it explicitly
i.e IF x >20 then RAISE …

Syntax:

EXCEPTION

WHEN exception1 [OR exception2...]] THEN

...

[WHEN exception3 [OR exception4...] THEN

...]

[WHEN OTHERS THEN

...]

Where exception is the exception_name e.g. WHEN NO_DATA_FOUND… Only one handler is processed before leaving the block.

Trap non-predefined errors by declaring them You can also associate the error no. with a name so that you can write a specific handler.
This is done with the PRAGMA EXCEPION_INIT pragma.

PRAGMA (pseudoinstructions) indicates that an item is a ‘compiler directive’ Running this has no immediate effect but causes all subsequent references to the exception name to be interpreted as the associated Oracle Error.

 

Trapping a non-predefined Oracle server exception

 

DECLARE

-- name for exception

e_emps_remaining EXCEPTION

PRAGMA_EXCEPTION_INIT (

e_emps_remaining, -2292);

v_deptno dept.deptno%TYPE :=&p_deptno;

 

BEGIN

DELETE FROM dept

WHERE deptno = v_deptno

COMMIT;

EXCEPTION

WHEN e_emps_remaining THEN

DBMS_OUTPUT.PUT_LINE ('Cannot remove dept '||

TO_CHAR(v_deptno) || '. Employees exist. ');

END;

When an exception occurs you can identify the associated error code/message with two supplied functions SQLCODE and SQLERRM

SQLCODE – Number

SQLERRM – message

 

An example of using these:

DECLARE
v_error_code NUMBER;
v_error_message VARCHAR2(255);

 

BEGIN

 

...

 

EXCEPTION

WHEN OTHERS THEN

ROLLBACK;

v_error_code := SQLCODE

v_error_message := SQLERRM

INSERT INTO t_errors

VALUES ( v_error_code, v_error_message);

END;

Trapping user-defined exceptions

DECLARE the exception

RAISE the exception

Handle the raised exception

 

e.g.

DECLARE

e_invalid_product EXCEPTION

BEGIN

update PRODUCT

SET descrip = '&prod_descr'

WHERE prodid = &prodnoumber';

IF SQL%NOTFOUND THEN

RAISE e_invalid_product;

END IF;

COMMIT;

EXCEPTION

WHEN e_invalid_product THEN

DBMS_OUTPUT.PUT_LINE ('INVALID PROD NO');

END;

Propagation of Exception handling in sub blocks

If a sub block does not have a handler for a particular error it will propagate to the enclosing block – where it can be caught by more general exception handlers.

RAISE_APPLICATION_ERROR (error_no, message[,{TRUE|FALSE}]);

 

This procedure  allows user defined error

messages from stored sub programs – call only from stored sub prog.

error_no = a user defined no (between -20000 and -20999)

 

TRUE = stack errors

FALSE = keep just last

 

This can either be used in the executable section of code or

the exception section

 

e.g.

EXCEPTION

WHEN NO_DATA_FOUND THEN

RAISE_APPLICATION_ERROR (-2021,

‘manager not a valid employee’);

END;

Standard Exceptions, from the the STANDARD package

Oracle Exception Name

Oracle Error

Explanation

DUP_VAL_ON_INDEX ORA-00001 You attempted to create a duplicate value in a field restricted by a unique index.
TIMEOUT_ON_RESOURCE ORA-00051 A resource timed out, took too long.
TRANSACTION_BACKED_OUT ORA-00061 The remote portion of a transaction has rolled back.
INVALID_CURSOR ORA-01001 The cursor does not yet exist. The cursor must be OPENed before any FETCH cursor or CLOSE cursor operation.
NOT_LOGGED_ON ORA-01012 You are not logged on.
LOGIN_DENIED ORA-01017 Invalid username/password.
NO_DATA_FOUND ORA-01403 No data was returned
TOO_MANY_ROWS ORA-01422 You tried to execute a SELECT INTO statement and more than one row was returned.
ZERO_DIVIDE ORA-01476 Divide by zero error.
INVALID_NUMBER ORA-01722 Converting a string to a number was unsuccessful.
STORAGE_ERROR ORA-06500 Out of memory.
PROGRAM_ERROR ORA-06501 Generic "Contact Oracle support" message.
VALUE_ERROR ORA-06502 You tried to perform an operation and there was a error on a conversion, truncation, or invalid constraining of numeric or character data.
ROWTYPE_MISMATCH ORA-06504  
CURSOR_ALREADY_OPEN ORA-06511 The cursor is already open.
ACCESS_INTO_NULL ORA-06530  
COLLECTION_IS_NULL ORA-06531  
       

Named exceptions

An exception can be given a name. In order to create such a named exceptions, two steps are necessary: first, it needs a line that reads exception_name exception. Then, this exception must be connected to a number with the pragma exception_init(exception_name, exc-number). The number must be in the range -20999 through -20000 (these are negative numbers!).
create or replace package exc as

  some_exc exception;

  pragma exception_init(some_exc, -20005);

  procedure raise_exc;
end exc;
/

create or replace package body exc as

  procedure raise_exc is begin 
    raise some_exc;
  end raise_exc;

end exc;
/
create or replace package use_exc as
  procedure do;
end use_exc;
/

create or replace package body use_exc as

  procedure do is begin

    exc.raise_exc;

    exception 
      when exc.some_exc then dbms_output.put_line('some_exc');
      when others       then dbms_output.put_line('others'  );

  end do;

end use_exc;
/
set serveroutput on
begin
  use_exc.do;
end;
/

The output:

some_exc

Reference -http://www.adp-gmbh.ch/ora/plsql/exception.html

Finding duplicate rows in SQL

Normally we want to fetch this information that which row have duplicate value.So here i am sharing very easy solution for this.by using this query you can get which row have multiple entries.

SELECT surname, 
 COUNT(surname) AS numOftimes
FROM employee
GROUP BY surname
HAVING ( COUNT(surname) > 1 )


You could also use this technique to find rows that occur exactly once or n time:

SELECT surname
FROM employee
GROUP BY surname
HAVING ( COUNT(surname) = 1 )
or for 'n' times


SELECT surname
FROM employee
GROUP BY surname
HAVING ( COUNT(surname) = n )

SQL Optimization Tips/Questions

Below are some of the tips for SQL query optimizations in the form of question/answers.

1. Which of the following query is the most optimized?
a. SELECT column_name FROM table_name WHERE LOWER(column_name) = ‘name’.
b. SELECT column_name FROM table_name WHERE column_name = ‘NAME’ or column_name = ‘name’.
c. SELECT * FROM table_name WHERE LOWER(column_name) = ‘name’
d. SELECT * FROM table_name WHERE column_name = ‘NAME’ or column_name = ‘name’.

Answer: B.
Reason: We should specify the columns in the Select queries and avoid functions like UPPER, LOWER etc as far as possible.

2. Which of the following query generally prevents (but not always) the query optimizer from using an index to perform a search?
a. SELECT member_number, first_name, last_name FROM members WHERE firstname like ‘m%’
b. SELECT member_number, first_name, last_name FROM members WHERE dateofbirth < DATEADD(yy,-21,GETDATE())
c. SELECT member_number, first_name, last_name FROM members WHERE DATEDIFF(yy,datofbirth,GETDATE()) > 21
d. All of these

Answer: C
Reason: Column name is mixed within a function. Hence index cannot be used by optimizer.

3. When we use “NOT IN” our SQL queries, the query optimizer uses which technique to perform the activity?
a. Indexing
b. Clustered Indexed scan
c. Nested table scan
d. None of these

Answer: C

4. Which of the following is the best way of inserting a binary image into database?
a. Use Insert statement
b. Use Stored procedure
c. Both give same performance
d. None of these

Answer: B
Reason: The reason for this is because the application must first convert the binary value into a character string (which doubles its size, thus increasing network traffic and taking more time) before it can be sent to the server. And when the server receives the character string, it then has to convert it back to the binary format (taking even more time).

5. SELECT INTO option locks the system tables. True or false?
Answer: True

6. Using which among “Derived table” and “Temporary table” can we reduce I/O and boost our application’s performance?
Answer: Derived table
Reason: A derived table is the result of using a SELECT statement in the FROM clause of an existing SELECT statement. By using derived tables instead of temporary tables, we can reduce I/O and boost our application’s performance.

7. Which of the following query is the best one in performance to verify the existence of a record in a table:
a. SELECT COUNT(*) FROM table_name WHERE column_name = ‘xxx’
b. IF EXISTS (SELECT * FROM table_name WHERE column_name = ‘xxx’)
c. Both give same performance

Answer: B
Reason: don’t use SELECT COUNT(*) in your Transact-SQL code to identify it, which is very inefficient and wastes server resources.

8. Which of the following is NOT recommended for UPDATE queries in order to reduce the amount of resources required to perform the query:
a. Try not to change the value of a column that is also the primary key.
b. Try to update a column that has a reference in the WHERE clause to the column being updated whenever possible
c. Try to avoid updating heavily indexed columns.
d. When updating VARCHAR columns, try to replace the contents with contents of the same length.

Answer: B
Reason: All points except “B” are recommended points for UPDATE queries. Instead we should try not to update a column that has a reference in the WHERE clause to the column being updated.

9. Omitting of which clause (if possible) can decrease the possibility that a sort operation will occur:
a. DISTINCT
b. ORDER BY
c. LIKE
d. Both A and B

Answer: D

10. Which of the following query will be better in performance?
a. SELECT * FROM Orders WHERE OrderID*3 = 33000
b. SELECT * FROM Orders WHERE OrderID = 33000/3
c. Both are same in terms of performance as well.

Answer: B
Reason: We should avoid computation on columns as far as possible and hence we will get an index scan instead of a seek.

kick it on DotNetKicks.com

Shout it

pimp it