13

我在带有“on commit drop”选项的函数中使用临时表。我的问题是,在某些情况下,一个更全局的函数可以调用第一个函数两次,所以“创建临时表”在提交之前被调用了两次——所以我有正常的错误“关系 [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

2 回答 2

17

...在“返回查询”中返回它的行,所以我不能在离开函数之前手动删除表。

其实你可以。你可以在你的情况下使用几个RETURN QUERY。手动后:

当一个 PL/pgSQL 函数被声明为返回 SETOF [...] 时,要返回的各个项目由一系列 RETURN NEXT 或 RETURN QUERY 命令指定,然后使用不带参数的最终 RETURN 命令来指示该函数已完成执行

所以你可以这样做:

RETURN QUERY
       SELECT * FROM my_temp_table;
DROP TABLE my_temp_table;
RETURN;
于 2015-10-07T17:26:42.267 回答
6

您可以删除表格以防万一

...
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;
...
于 2015-10-07T17:25:23.033 回答