Ошибка ORA-01422: exact fetch returns more than requested number of rows
- Ошибка
ORA-01422: exact fetch returns more than requested number of rowsв PL/SQL. - Сбой пакетов при попытке поместить результат многострочного запроса в скалярную переменную через
SELECT ... INTO .... - Нарушение бизнес-логики из-за появления дублирующихся записей в таблице-справочнике.
1. Использование курсоров для пакетного чтения (BULK COLLECT)
Если запрос может возвращать множество строк, используйте коллекции:
DECLARE
TYPE t_vals IS TABLE OF my_table.val%TYPE;
v_vals t_vals;
BEGIN
SELECT val BULK COLLECT INTO v_vals
FROM my_table
WHERE status = 'ACTIVE';
FOR i IN 1..v_vals.COUNT LOOP
DBMS_OUTPUT.PUT_LINE(v_vals(i));
END LOOP;
END;2. Ограничение выборки одной строкой (ROWNUM = 1 / FETCH FIRST)
SELECT val INTO v_val
FROM my_table
WHERE status = 'ACTIVE'
ORDER BY created_date DESC
FETCH FIRST 1 ROW ONLY;3. Перехват исключения TOO_MANY_ROWS в блоке EXCEPTION
BEGIN
SELECT val INTO v_val FROM my_table WHERE code = 'EUR';
EXCEPTION
WHEN TOO_MANY_ROWS THEN
-- Обработка аномалии дублирования данных
v_val := 'ERROR_DUPLICATE';
END; Частые вопросы (FAQ)
Почему ORA-01422 считается критической логической ошибкой?
Конструкция SELECT INTO проектируется в расчете на строгую уникальность ключа. Появление второй строки говорит о нарушении целостности данных или отсутствии уникального индекса.
Вызывает ли использование DISTINCT защиту от ORA-01422?
Только если все возвращаемые строки полностью идентичны по значениям. Если значения различаются, DISTINCT вернет 2+ строки и ошибка ORA-01422 повторится.
Как быстро найти дублирующиеся строки, вызвавшие ORA-01422?
Сгруппируйте данные: SELECT key_col, COUNT(*) FROM target_table GROUP BY key_col HAVING COUNT(*) > 1;.
В чем разница между явным курсором (CURSOR c IS) и SELECT INTO при выборке 2 строк?
Явный курсор (OPEN/FETCH) просто прочитает первую строку без ошибки, если не запросить вторую. SELECT INTO выполняет проверку 'exact fetch' и выбрасывает ORA-01422 при обнаружении второй строки.