How to Fix ORA-01403: No Data Found in Oracle PL/SQL

Understand why SELECT INTO raises NO_DATA_FOUND, handle it where a missing row is normal, and watch for it in functions called from SQL.

ORA-01403 is raised when a SELECT INTO statement in PL/SQL returns no row. SELECT INTO must fill its variables with exactly one row, so an empty result is an error, raised as the predefined exception NO_DATA_FOUND. The fix depends on whether a missing row is normal: handle the exception where it can happen, or write the query so that it always returns one row.

Reproduce the Error

Example:

create table demo_fares (route_code varchar2(10) primary key, fare number);
insert into demo_fares values ('DEL-BOM', 120);
insert into demo_fares values ('DEL-DXB', 310);
commit;
set serveroutput on
declare
  v_fare demo_fares.fare%type;
begin
  select fare into v_fare from demo_fares where route_code = 'DEL-LHR';
  dbms_output.put_line('Fare: ' || v_fare);
end;
/

Output:

Table DEMO_FARES created.

1 row inserted.

1 row inserted.

Commit complete.

declare
*
ERROR at line 1:
ORA-01403: no data found
ORA-06512: at line 4

Line 4 of the block is the SELECT INTO; no route DEL-LHR exists.

Fix: Handle the Missing Row

Example:

set serveroutput on
-- handle the missing row where it can happen
declare
  v_fare demo_fares.fare%type;
begin
  begin
    select fare into v_fare from demo_fares where route_code = 'DEL-LHR';
  exception
    when no_data_found then
      v_fare := null;
  end;
  dbms_output.put_line('Fare: ' || nvl(to_char(v_fare), 'not on sale'));
end;
/
-- or use an aggregate, which always returns one row
declare
  v_fare demo_fares.fare%type;
begin
  select max(fare) into v_fare from demo_fares where route_code = 'DEL-LHR';
  dbms_output.put_line('Fare: ' || nvl(to_char(v_fare), 'not on sale'));
end;
/

Output:

Fare: not on sale

PL/SQL procedure successfully completed.

Fare: not on sale

PL/SQL procedure successfully completed.
  • The first block wraps the SELECT INTO in its own BEGIN ... EXCEPTION ... END, so only that query's missing row is handled, and the code continues.
  • The second block uses MAX: an aggregate without GROUP BY always returns one row, NULL when nothing matches.

NO_DATA_FOUND in Functions Called from SQL

When a function raises NO_DATA_FOUND inside a SQL statement, SQL treats it as no value instead of an error:

Example:

-- a function that raises NO_DATA_FOUND, called from SQL
create or replace function demo_fare_of (p_route varchar2) return number is
  v_fare number;
begin
  select fare into v_fare from demo_fares where route_code = p_route;
  return v_fare;
end;
/
select demo_fare_of('DEL-LHR') as fare from dual;

Output:

Function DEMO_FARE_OF compiled

   FARE
_______

The query returns NULL without any error, which can hide a real problem. Handle the exception inside such functions and return a deliberate value, or raise a different error.

Things to Know

  • Reading an associative array element that does not exist also raises ORA-01403.
  • A cursor FETCH that finds no more rows does not raise it; it sets %NOTFOUND instead.
  • Avoid WHEN OTHERS THEN NULL as a fix: it hides every other error too.

Related Guides

Conclusion

ORA-01403 means a SELECT INTO found no row. Decide whether that is normal; if it is, handle NO_DATA_FOUND around that query or use an aggregate that always returns a row, and if not, let the error reach the caller with a clear message.

Get more Vinish.dev tutorials on Google

See my articles more often when you search Google.

Vinish Kapoor
Vinish Kapoor

An Oracle ACE, author of four books on Oracle APEX, SQL and PL/SQL, and Oracle Forms, and a software developer building Oracle database applications since 2001.

guest

0 Comments
Oldest
Newest Most Voted