函数无法在段上执行,因为它访问关系

问题描述 投票:2回答:3

我在Greenplum postgres中具有如下定义的功能

CREATE OR REPLACE FUNCTION vin_temp_func(j text) RETURNS integer AS $$
Declare varx integer;
BEGIN
select count(*) into varx
from T_perf a
left join T_profile b on a.sr_number = b.sr_number  where b.product_name like '%V1%' and
a.submit_date >= (('2013-02-01'::date - CAST(EXTRACT(DOW FROM '2013-02-01'::date) as int)) - 7)+'1 week'::interval and 
a.submit_date <= ('2013-02-01'::date - CAST(EXTRACT(DOW FROM '2013-02-01'::date)+1 as int)) + '1 week'::interval+'23 hours'::interval+'59 minutes'::interval+'59 seconds'::interval
and b.product_name = j;
RETURN varx;
        END;
$$ LANGUAGE plpgsql;

像这样定义的表

drop table if exists prod_week_A;

create table prod_week_A as (
select product_name 
from T_profile where product_name like '%V1%' limit 100)

[当我尝试执行以下命令时,出现错误“函数无法访问,因为它访问关系”

select product_name, vin_temp_func(product_name) 
from prod_week_A limit 100;

[有人可以帮我解决这个问题吗?谢谢!

sql greenplum
3个回答
1
投票

与Postgress相比,Greenplum中的功能受到限制。如果一个函数访问一个“关系”(思维表),则不能在另一个表的选择中调用它。

因此可以手动调用函数

select vin_temp_func('product1')

将起作用。但正如您所见

select product_name, vin_temp_func(product_name) from prod_week_A limit 100;

将会给您该错误。

您可能可以将函数重写为视图,这在很多情况下是可能的,但是在这里可能很困难。


0
投票

我处于类似情况。

* 从prod_week_A中选择产品名称,vin_temp_func(产品名称); *

有效的方法很奇怪,我对此并不了解。我限制了要从中提取行的表的结果。所以

* 选择产品名称,vin_temp_func(产品名称)从(从prod_week_A限制中选择产品名称10000000)a; *]

我在限制前面放了一个大数字,以返回所有行。需要时间(本不应该这样),但是可以。

请尝试一下,让我知道这是否也适合您。


0
投票

我遇到类似的问题。

INSERT INTO tableX SELECT * from function_name(...);

Wes Reing的观点似乎准确无误-GPDB确实不想从引用另一个表的语句中调用您的函数。因此,我决定在pl / sql中拆分各个部分。

DO $$
DECLARE 
  myrow myrowtype;
BEGIN
  SELECT * FROM function_name(...) INTO myrow;
  INSERT INTO tableX (...) (SELECT myrow.*);
  RETURN;
END;
$$ LANGUAGE plpgsql;

这将在master(?)上收集函数的输出,然后在INSERT期间将其推回分段。这比我们最初想要的要理想的要差一些,这是将函数的输出直接推到段上的表中,但是在我们看来,性能下降和主服务器增加的负担似乎并不大情况。

希望您可以将此想法适应您的问题。

祝你好运!

© www.soinside.com 2019 - 2024. All rights reserved.