Если вы выбираете из разных таблиц, я бы использовал следующее - в качестве альтернативы можно использовать курсор, если один и тот же запрос используется только с изменяющимся параметром (например, id), в этом случае вы можете использовать параметры курсора.
DECLARE
v_count PLS_INTEGER;
BEGIN
SELECT COUNT(*)
INTO v_count
FROM sample_table
WHERE id=3;
CASE v_count
WHEN 0 THEN dbms_output.put_line('FALSE');
ELSE dbms_output.put_line('TRUE');
END CASE;
END;
Важно использовать COUNT (*), а не считать поле, поскольку COUNT (*) по-прежнему возвращает 0, если записей не существует.
Изменить, чтобы добавить: эквивалент курсора
DECLARE
v_count PLS_INTEGER;
CURSOR count_cur(cp_id sample_table.id%TYPE)
IS
SELECT COUNT(*)
FROM sample_table
WHERE id = cp_id;
BEGIN
OPEN count_cur(3);
FETCH count_cur INTO v_count;
CLOSE count_cur;
CASE v_count
WHEN 0 THEN dbms_output.put_line('FALSE');
ELSE dbms_output.put_line('TRUE');
END CASE;
END;
Есть также тесты, доступные на курсорах, таких как курсор% FOUND или курсор% NOTFOUND, к которым можно получить доступ после открытия курсора. Хотя, если все, что вы делаете, это проверяете, существует ли запись, которая может быть более многословной.
Также имейте в виду, что если вы выполняете оператор SELECT INTO, то, если вы не выполняете COUNT (*), который гарантированно всегда возвращает запись, то это хорошая форма, чтобы перехватить возможное слишком большое количество исключений или исключений из них.