Логики if-else можно полностью избежать.Эквивалентный результат может быть записан как один запрос.Функция BOOL_AND
является агрегатной функцией, которая возвращает false
, если любое из значений равно false
, в противном случае она возвращает true
.
Следующий запрос будет работать правильно, даже если несколько строк соответствуют условию lower(name) like '<namevalue>'
или если у вас есть несколько значений по умолчанию.
SELECT subquery.id, subquery.name, subquery.isdefault
FROM (SELECT d.id,
d.name,
d.isdefault,
BOOL_AND(d.isdefault) OVER () default_and
FROM domain d
WHERE lower(d.name) like 'robert' or isdefault) subquery
WHERE isdefault = default_and
Относительно того, почему вы получаете ошибку сIF EXISTS(temporal_result)
, это недействительно sql.Запрещается делать такое ветвление внутри оператора SQL.Вместо этого вы можете сохранить результат первого запроса во временную таблицу и выполнить ветвление if-else со ссылкой на временную таблицу.Ниже приведена правильная версия хранимой процедуры:
CREATE OR REPLACE FUNCTION mytestprocedure(namevalue character varying)
RETURNS TABLE(id integer, name character varying, isdefault boolean)
LANGUAGE plpgsql
AS $function$
BEGIN
CREATE TEMPORARY TABLE temporal_result as
SELECT
d.id,
d.name,
d.isdefault
FROM domain d
where lower(d.name) like namevalue
;
IF EXISTS(SELECT TRUE FROM temporal_result) THEN
RETURN QUERY SELECT * from temporal_result;
ELSE
RETURN QUERY SELECT
d.id,
d.name,
d.isdefault
FROM domain d
where d.isdefault = true;
END IF;
DROP TABLE temporal_result;
RETURN;
END;
$function$;
Обратите внимание, что необходимо удалить таблицу в конце процедуры.
Также обратите внимание, что postgresql игнорирует прописные / строчные буквы в именах сущностей, если они не заключены в кавычки, поэтому обычно считается плохим стилем использовать регистр верблюдов при именовании таблиц / полей / функций.