Какой самый правильный и провереный способ проверки наличия записи в таблице в PL/SQL блоке?
Какой есть правильный и провереный способ проверки наличия записи в таблице, когда использую PL/SQL блок?
Например, есть таблица PERSON (ID, Name). Очевидно, что нельзя сделать (если только нет какого-нибудь секретного метода) что-то в этом роде:
BEGIN
IF EXISTS SELECT id FROM person WHERE ID = 10;
-- делать что-то если запись найдена
ELSE
-- делать что-то если запись еще не сушествует
END IF;
END;
Так что использую такой стандартный способ решения:
DECLARE
tmp NUMBER;
BEGIN
SELECT id INTO tmp FROM person WHERE id = 10;
-- делать что-то если запись найдена
EXCEPTION
WHEN no_data_found THEN
-- делать что-то если запись еще не сушествует
END;
Однако, не уверен, принято ли это так делать, или есть лучший способ проверки.
Свободный перевод вопроса Proper way of checking if row exists in table in pl/sql block от участника @devBem
Ответы (2 шт):
Не стоит помещать код с обычной логикой в блок исключений, там должна быть только обработка исключений.
Сначала проверьте, есть ли записи, и далее реализуйте логику по результатам проверки:
declare
cursor cur is select 1 from person where id=10;
found boolean := false;
begin
open cur; found := cur%found;
close cur;
if found then
null; -- делать что-то если запись найдена
else
null; -- делать что-то если запись еще не сушествует
end if;
exception when others then
null; -- делать что-то с исключением
end;
/
Или так с неявным курсором:
declare
found boolean := false;
begin
<<checkIfExists>>
for r in (select 1 from person where id=10) loop
found := true;
exit checkIfExists;
end loop;
if found then
null; -- делать что-то если запись найдена
else
null; -- делать что-то если запись еще не сушествует
end if;
exception when others then
null; -- делать что-то с исключением
end;
/
Не стал бы вставлять обычный код в блок исключений.
Просто проверьте, есть ли строки, которые отвечают вашему условию, и продолжайте дальше:
declare
any_rows_found number;
begin
select count(*)
into any_rows_found
from my_table
where rownum = 1 and
... other conditions ...
if any_rows_found = 1 then
...
else
...
end if;
Свободный перевод ответа участника @David Aldridge