2015-10-07 107 views
2

我在'on commit drop'选项中使用函数中的临时表。我的问题是,在某些情况下,更多的全局函数可以调用第一个函数两次,因此在提交之前调用两次“create temp table” - 所以我有正常的错误“relation [my_temp_table]已经存在”。退出函数时删除临时表

我在函数的末尾使用临时表来返回其在“返回查询”中的行,所以在离开函数之前我不能手动删除表。

CREATE OR REPLACE FUNCTION my_function(_value text) 
RETURNS setof my_table AS $$ 
DECLARE 
    resultCount integer := 0; 
BEGIN 

    create temp table my_temp_table on commit drop as 
    select * 
    from my_table 
    where value = _value ; 

    select count(*) into resultCount from my_temp_table; 
    if (resultCount = 0) then 
     raise exception 'value not found'; 
     end if; 

    return query 
    select * from my_temp_table; 

END;$$ LANGUAGE plpgsql VOLATILE COST 100; 
ALTER FUNCTION my_function(text) OWNER TO postgres 

如果你想知道为什么我用一个临时表,而不是MY_TABLE直接的方式,那是因为我需要一个非常快速的响应和MY_TABLE是非常大的(几十几百万行),所以这样我可以要求它只有一次而不是三次(搜索,计数和返回)。

我找到了一个不使用临时表和创建类型的解决方法,但my_table的结构会改变很多次,实际上我有几十个“我的表”和有关“我的函数”,所以这是一种方法每次我的表格结构都会改变时,不要再写所有的函数。

函数必须返回与它请求的表相同的结构。

如何在离开功能时放下桌子?还是有更好的解决方法?

回答

4

...在“返回查询”返回其行,所以我无法手动删除该表之前,我离开的功能。

其实你可以。你可以使用几个RETURN QUERY。 手册后:

当PL/pgSQL函数被声明为返回SETOF [...]的各个项目,返回通过RETURN NEXT或RETURN QUERY命令的序列被指定,然后,在最后RETURN指令不带参数用来表示该功能已执行完毕

所以,你可以这样做:

RETURN QUERY 
     SELECT * FROM my_temp_table; 
DROP TABLE my_temp_table; 
RETURN; 
+0

非常感谢这是完美的! –

+0

此代码会引发错误。 –

2

你可以删除该表以防万一

... 
BEGIN 
    drop table if exists my_temp_table; 
    create temp table my_temp_table on commit drop as 
    .... 

但......其实你并不需要一个临时表。试试这个代码:

... 
    return query 
    select * 
    from my_table 
    where value = _value ; 

    if not found then 
     raise exception 'value not found'; 
    end if; 
... 
+0

我会用下面的最终“回归”,但我会definitly用“如果不是发现“!非常感谢 ! –

+0

@ThomasPerrin - 这真的不管回报声明在哪里。 Klin为你提供了完整的功能,只需测试一下。 –

+0

是的,它的工作原理,谢谢 –