Проблема Greenplum: функция не может выполняться в сегменте, поскольку она обращается к отношению

Я использую базу данных Greenplum. Ниже приведено определение функции, которую я использовал для выполнения.

CREATE OR REPLACE FUNCTION testfunc(IN id int, OUT rate double precision)
RETURNS double precision AS
$BODY$
begin
select count(*) into rate from ref_test_V
return;
end;
$BODY$
  LANGUAGE plpgsql VOLATILE;

И когда я вызываю эту функцию в списке выбора, она выдает мне ошибку ниже

Запрос: выберите 1,testfunc(id) из ref_test

ОШИБКА: XX000: функция не может выполняться в сегменте, так как обращается к отношению public.ref_test_v (functions.c:155) (seg25 slice1 *****.com 1026 pid=193132) (cdbdisp.c: 1326)


person jaga    schedule 01.07.2016    source источник


Ответы (2)


Это не поддерживается в Greenplum. Подумайте о том, что бы он делал, если бы его поддерживали. Он получит одну строку из сегмента, а затем сделает count(*) сам с собой. Будет получена следующая строка, и она снова сделает подсчет (*).

Чистый способ SQL сделать это:

with x as (select count(*) as total_count from ref_test_V)
select 1, x.total_count from ref_test, x;

Если вам не нравится использовать Common Table Expression, вы можете сделать это с помощью подзапроса.

select 1, x.total_count 
from   ref_test, 
       (select count(*) as total_count 
       from ref_test_V) as x;
person Jon Roberts    schedule 01.07.2016
comment
Я понимаю это, но я пытаюсь спросить, что я хочу получить количество некоторой таблицы со значением фильтра на основе аргумента из функции, и функция вызывается из другой таблицы в списке выбора. Если мой синтаксис неверен, не могли бы вы указать мне правильный синтаксис. Пример кода мне поможет. Обратите внимание, что я не хочу реализовывать как SQL. ТИА :) - person jaga; 02.07.2016
comment
Вам нужно будет выполнить два разных оператора SQL (один с подсчетом, а следующий с другим выбором) или использовать переменную в функции для сбора количества записей. - person Jon Roberts; 03.07.2016
comment
Я попробовал, как вы сказали, но проблема все еще сохраняется. Не могли бы вы предоставить любой пример кода, который мог бы мне помочь. Я пробовал все, чтобы прочитать количество записей таблицы из функции, и когда я вызываю эту функцию из списка выбора другой таблицы, продолжаю получать ту же проблему. ТИА - person jaga; 04.07.2016
comment
:) Я хочу сообщить, что моя функция более критична, чем то, что я объяснил в этом блоге, и проблема вызвана тем, о чем я говорил ранее, поэтому я сделал ее простой. Я не могу реализовать эту функцию как SQL или как CTE из-за ее сложности. Надеюсь, если вы могли бы помочь мне найти решение этой проблемы. - person jaga; 05.07.2016
comment
Я думаю, вы пытаетесь использовать функции не так, как в Greenplum. Вы должны ограничить использование функций во встроенном SQL, если только вы не инкапсулируете общие преобразования данных. Вы пытаетесь использовать его для запроса таблицы, чего делать не следует. - person Jon Roberts; 05.07.2016
comment
Невозможно ли прочитать данные таблицы из функции при вызове из списка выбора. Вышеупомянутая функция работает при отдельном вызове с постоянными значениями в качестве аргумента, но не работает при вызове в списке выбора. Надеюсь, есть ли другой способ преодолеть это или встроенный SQL - единственный способ - person jaga; 05.07.2016
comment
Это возможно, но это не может быть одна и та же таблица. Но функция выполняется для каждой возвращаемой строки, так что это очень неэффективный способ. Подзапрос или CTE были бы лучшим выбором. - person Jon Roberts; 05.07.2016
comment
Да, я согласен, и я также пробовал с двумя разными таблицами, но проблема остается. Да, подзапрос или CTE были бы более эффективными, но сложность функции заставила меня пойти с преобразованием функции. Поэтому было бы полезно, если бы вы могли показать мне правильный синтаксис для вышеупомянутой функции, чтобы я мог реализовать это в своей функции. - person jaga; 05.07.2016
comment
Это не поддерживается. - person Jon Roberts; 05.07.2016

Вызовите функцию из таблицы, как показано ниже.

select 1, (select testfunc(5)) from ref_test;
person Syamala    schedule 11.07.2016
comment
Он работает, если вы передаете постоянное значение в качестве параметра, он не работает, когда вы передаете столбец из ref_test , это то, что я имею в виду. - person jaga; 13.07.2016