Go4Expert

Go4Expert (http://www.go4expert.com/)
-   Oracle (http://www.go4expert.com/articles/oracle/)
-   -   Avoiding TOO_MANY_ROWS Error In Oracle (http://www.go4expert.com/articles/avoiding-toomanyrows-error-oracle-t7637/)

pradeep 30Nov2007 15:51

Avoiding TOO_MANY_ROWS Error In Oracle
 
When you use SELECT in a PL/SQL block, it's important to make sure that exactly one row will always be returned by your query. If more than one row is returned, the TOO_MANY_ROWS exception occurs. There are four ways to make sure your code is safe from this error...

Oracle's PL/SQL language has two basic mechanisms for getting data from the database: SELECT and cursors. SELECT is designed to return a single row into local variables; cursors give you the ability to select multiple rows (i.e., a "rowset") and process them one at a time.

When you use SELECT in a PL/SQL block, it's important to make sure that exactly one row will always be returned by your query. If more than one row is returned, the TOO_MANY_ROWS exception occurs. Listing A shows an example from Oracle's HR sample schema: There is more than one employee with the last name Shabbir, so the script fails.

Code: SQL

DECLARE
 
 l_employee_last_name employees.last_name%TYPE;
 l_employee_full_name VARCHAR2(52);
 
 BEGIN
 
 l_employee_last_name := 'Shabbir';
 
 SELECT last_name || ', ' || first_name
 INTO l_employee_full_name
 FROM employees
 WHERE last_name = l_employee_last_name;
 
 DBMS_OUTPUT.PUT_LINE (l_employee_full_name);
 
 END;
 /

There are four ways to make sure your code is safe from this error.
  • Select rows using the primary key. In Listing A, I selected by last_name, and it's quite likely there will be more than one employee with the same last name. If I change the code to select by employee_id instead, I'll avoid the error because only one row in a table can have the same value in the primary key column(s).
  • Select aggregate functions. By definition, the aggregate functions (AVERAGE, COUNT, MIN, MAX, and SUM) return only one row as a result. Even if its WHERE clause has no matching rows, a COUNT of those rows will return one row -- the answer "0." Selecting the MIN or MAX of a table is frequently done in this way to determine processing limits.
  • Limit the query using ROWNUM. If there is a possibility of returning multiple rows, but any row is as good as any other row, try adding the following condition to the query: AND ROWNUM < 2. This will limit the results to the first row of the set. But remember that it's the first physical row returned -- adding ORDER BY to a query with ROWNUM in it will not give you the highest or lowest row, only the first one.
  • Put the SELECT in its own block. If you surround the SELECT with its own inner block, you can code an exception handler to supply a reasonable value if an error occurs. Listing B shows the previous query enhanced in this way.
Code: SQL

DECLARE
 
 l_employee_last_name employees.last_name%TYPE;
 l_employee_full_name VARCHAR2(52);
 
 BEGIN
 
 l_employee_last_name := 'Shabbir';
 
 BEGIN
 SELECT last_name || ', ' || first_name
 INTO l_employee_full_name
 FROM employees
 WHERE last_name = l_employee_last_name;
 EXCEPTION
 WHEN NO_DATA_FOUND THEN
 l_employee_full_name := '(not on file)';
 WHEN TOO_MANY_ROWS THEN
 l_employee_full_name := '(duplicate name)';
 END;
 
 DBMS_OUTPUT.PUT_LINE (l_employee_full_name);
 
 END;
 /


shabbir 1Dec2007 17:59

Re: Avoiding TOO_MANY_ROWS Error In Oracle
 
I have reported the article for Nominate your favorite article of the month for November 2007. Add your nominations as well.

lead.smart34 26Feb2008 17:47

Re: Avoiding TOO_MANY_ROWS Error In Oracle
 
good explanation.


All times are GMT +5.5. The time now is 08:12.