NO_DATA_FOUND vs TOO_MANY_ROWS
A SELECT INTO must return exactly one row: zero rows raises NO_DATA_FOUND, more than one raises TOO_MANY_ROWS.
How it works
SELECT ... INTO is for singleton queries. Zero rows raises NO_DATA_FOUND (ORA-01403 — also raised by an unmatched associative-array lookup and by a PL/SQL function that ends without RETURN). Two or more rows raises TOO_MANY_ROWS (ORA-01422) and the variable is left unassigned. Handle both explicitly, or restructure: use an aggregate (MAX/COUNT) that always returns one row, or a cursor / BULK COLLECT when many rows are legitimate. Note that aggregates make NO_DATA_FOUND impossible — SUM over no rows returns NULL, one row.
DECLARE
v_name employees.last_name%TYPE;
BEGIN
SELECT last_name INTO v_name FROM employees WHERE department_id = 30;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('no employee in dept 30');
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_LINE('more than one - use a cursor instead');
END;
/Related questions
Model-generated, grounded against the curated knowledge layer. Check specifics against your instance.