Как проверить, существует ли строка в хранимой процедуре PostgreSQL?

Я пишу хранимую процедуру в postgres, где мне нужно проверить, существует ли строка, а затем действовать соответствующим образом. что-то вдоль линии.

IF SELECT * FROM foo WHERE x = 'abc' AND y = 'xyz' THEN
  -- do something here
ELSE 
  -- do something else
END;

Я немного искал Google, но не получал хороших хитов.

Ответ 1

Используйте PERFORM и автоматическую переменную FOUND:

PERFORM * FROM foo WHERE x = 'abc' AND y = 'xyz';
IF FOUND THEN
    ....
END IF;

Это будет успешным, если будет возвращена одна или несколько строк. Если вы хотите ограничить результат точностью до одной строки использовать GET DIAGNOSTICS для получения числа строк или использовать SELECT INTO для хранения count(...) строк в переменную DECLARE d, которую вы затем проверяете. Если это ошибка, чтобы получить никаких результатов, используйте SELECT INTO STRICT, чтобы потребовать, чтобы ровно одна строка была получена и сохранена в целевой переменной.

Остерегайтесь проблем concurrency при выполнении чего-либо подобного. Если вы пытаетесь написать функцию upsert/merge, этот подход не будет работать. См. "почему это так сложно" .

Ответ 2

Или даже проще с EXISTS:

IF EXISTS (SELECT 1 FROM foo WHERE x = 'abc' AND y = 'xyz') THEN
    ....
END IF;