Использование PERFORM в рекурсивной функции запроса в postgresql - PullRequest
0 голосов
/ 27 февраля 2019

У меня есть рекурсивный запрос, который я хочу использовать в функции postgresql, и он должен возвращать логическое значение.

CREATE OR REPLACE FUNCTION store.is_item(object1 VARCHAR(40), object2 VARCHAR(40))
RETURNS BOOLEAN AS $$
BEGIN
   WITH RECURSIVE externals AS (
   SELECT object_id, used_id
   FROM store.obj_depend
   WHERE external = true
   ), history AS (
   SELECT content_id AS id
   FROM store.minfos
   WHERE id= $2
   UNION
   SELECT externals.used_id
   FROM externals
   INNER JOIN history ON history.id = externals.object_id
   ),
   PERFORM (SELECT c.id FROM store.cinfo AS c WHERE c.id = $1 INNER JOIN history 
   ON c.id = history.id);
   RETURN FOUND;
END;
$$ LANGUAGE plpgsql;

Когда я пытаюсь это сделать, он выдает ошибку syntax error at or near SELECT

1 Ответ

0 голосов
/ 28 февраля 2019

PERFORM является оператором plpgsql и не может использоваться внутри любой команды SQL.

Вы можете использовать PERFORM как предложенный @klin, но тогда CTE используется внутри подзапроса, а подзапрос возвращает одну строкукаждый раз.Тогда переменная FOUND должна быть каждый раз истинной.

В этом случае лучше использовать вспомогательную переменную в качестве targer:

CREATE OR REPLACE FUNCTION store.is_item(object1 VARCHAR(40), object2 VARCHAR(40))
RETURNS BOOLEAN AS $$
DECLARE r record;
BEGIN
  WITH RECURSIVE 
    externals AS (SELECT object_id, used_id
                    FROM store.obj_depend
                   WHERE external = true)
    history AS (SELECT content_id AS id
                  FROM store.minfos
                 WHERE id = object2
                UNION
                SELECT externals.used_id
                  FROM externals
                       INNER JOIN history ON history.id = externals.object_id)
  SELECT c.id
    FROM store.cinfo AS c 
         INNER JOIN history ON c.id = history.id
   WHERE c.id = $1 
    INTO r;
  RETURN FOUND;
END;
$$ LANGUAGE plpgsql; 
...