Ошибка при создании процедуры содержащую команду EXECUTE

Задача: необходимо создать хранимую процедуру, которая

  1. получает некоторый sql запрос в виде строки типа VARCHAR в качестве аргумента (сам запрос возвращает выборку из некоторой таблицы)
  2. выполняет его
  3. проводит фильтрацию по полученной выборке
  4. Возвращает результат указывающий - есть ли хотя бы одна строка в выборке или нет

В моем случае эта процедура выглядит так:

CREATE FUNCTION existProductsForFilter(productCategories VARCHAR(256)[], filterQuery VARCHAR(2048))
    RETURNS BOOLEAN
    LANGUAGE plpgsql
    AS $BODY$
BEGIN
    RETURN EXISTS (
        SELECT * FROM (EXECUTE filterQuery) AS P
            WHERE P.category = ANY(productCategories)
    );
END;
$BODY$;

Что не получается: при попытке создать вышеуказанную процедуру я получаю ошибку
ERROR: ОШИБКА: ошибка синтаксиса (примерное положение: ")")
LINE 7: SELECT * FROM (EXECUTE filterQuery) AS P

Я просмотрел множество примеров использования ключевого слова EXECUTE, но так и не смог понять, в чем ошибка.


Ответы (1 шт):

Автор решения: roamer

Похожая задача была. Решил след образом:

CREATE OR REPLACE FUNCTION public.exec_select(query text)
  RETURNS SETOF record AS
$BODY$
begin
  /*
  Выполнить запрос (SELECT ) заданный во входном параметре типа text.
  Пример: 
    select * from exec_select('code, name_max::t_namemax from public.props_types where code>0') as ds(code integer, name_max t_namemax);
    select * from exec_select('code::integer, name_max::t_namemax from public.props_types where code>0') as ds(code integer, name_max t_namemax);
    select * from exec_select('code, name_max::t_namemax from public.props_types where upper(mnemocode)=' || upper(chr(39) || 'time' || chr(39))  ) as ds(code integer, name_max t_namemax);    
    select * from exec_select('code, name_max::t_namemax from public.props_types where upper(mnemocode)=' || upper(q39_add_lr('time'))) as ds(code integer, name_max t_namemax);    
    select * from exec_select('code, name_max::text from public.props_types where code>0') as ds(code integer, name_max text);
  */ 
  return query execute 'select ' || query;
end;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100
  ROWS 1000;

===========

CREATE OR REPLACE FUNCTION public.exec_sql_select(query text)
  RETURNS SETOF record AS
$BODY$
begin
  /*
  Пример: 
    Выполнить запрос SELECT заданный во входном параметре типа text
    select * from exec_select('code, name_max::t_namemax from public.props_types where code>0') as ds(code integer, name_max t_namemax);
    select * from exec_select('code::integer, name_max::t_namemax from public.props_types where code>0') as ds(code integer, name_max t_namemax);
    select * from exec_select('code, name_max::t_namemax from public.props_types where upper(mnemocode)=' || upper(chr(39) || 'time' || chr(39))  ) as ds(code integer, name_max t_namemax);    
    select * from exec_select('code, name_max::t_namemax from public.props_types where upper(mnemocode)=' || upper(q39_add_lr('time'))) as ds(code integer, name_max t_namemax);    
    select * from exec_select('code, name_max::text from public.props_types where code>0') as ds(code integer, name_max text);
    select * from exec_select('code, name_max::text from public.props_types where mnemocode=' ||  q39_lr(null)) as ds(code integer, name_max text);
    select * from exec_select('code, name_max::text from public.props_types where code > ' || '0') as ds(code integer, name_max text);
  */ 
  return query execute query;
end;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100
  ROWS 1000;
→ Ссылка