我在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;
[有人可以帮我解决这个问题吗?谢谢!
与Postgress相比,Greenplum中的功能受到限制。如果一个函数访问一个“关系”(思维表),则不能在另一个表的选择中调用它。
因此可以手动调用函数
select vin_temp_func('product1')
将起作用。但正如您所见
select product_name, vin_temp_func(product_name)
from prod_week_A limit 100;
将会给您该错误。
您可能可以将函数重写为视图,这在很多情况下是可能的,但是在这里可能很困难。
我处于类似情况。
* 从prod_week_A中选择产品名称,vin_temp_func(产品名称); *
有效的方法很奇怪,我对此并不了解。我限制了要从中提取行的表的结果。所以
* 选择产品名称,vin_temp_func(产品名称)从(从prod_week_A限制中选择产品名称10000000)a; *]
我在限制前面放了一个大数字,以返回所有行。需要时间(本不应该这样),但是可以。
请尝试一下,让我知道这是否也适合您。
我遇到类似的问题。
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期间将其推回分段。这比我们最初想要的要理想的要差一些,这是将函数的输出直接推到段上的表中,但是在我们看来,性能下降和主服务器增加的负担似乎并不大情况。
希望您可以将此想法适应您的问题。
祝你好运!