PostgreSQL(9.4)临时表范围

时间:2015-09-29 14:24:39

标签: postgresql scope temp-tables

在一些恶化之后,当一个函数调用另一个函数时,我发现(IMO)奇怪的行为。如果外部函数创建了一个临时表,并且内部函数创建了一个具有相同名称的临时表,则内部函数"获胜。"这是有意的吗? FWIW,我精通SQL Server,临时表不会这样做。临时表(#temp@temp)的范围限定在函数中。因此,等效函数(SQL Server存储过程)将返回" 7890,"不是" 1234。"

drop function if exists inner_function();
drop function if exists outer_function();

create function inner_function()
returns integer
as
$$
begin
    drop table if exists tempTable;
    create temporary table tempTable (
        inner_id int
    );
    insert into tempTable (inner_id) values (1234);
    return 56;
end;
$$
language plpgsql;

create function outer_function()
returns table (
    return_id integer
)
as
$$
    declare intReturn integer;
begin
    drop table if exists tempTable; -- note that inner_function() also declares tempTable
    create temporary table tempTable (
         outer_id integer
    );
    insert into tempTable (outer_id) values (7890);
    intReturn = inner_function(); -- the inner_function() function recreates tempTable
    return query
        select * from tempTable; -- returns "1234", not "7890" like I expected
end;
$$
language plpgsql;

select * from outer_function(); -- returns "1234", not "7890" like I expected

2 个答案:

答案 0 :(得分:2)

这种行为没有问题,在PostgreSQL中临时表可以有两个范围: - 会话(默认) - 交易

使用"交易"你应该使用的范围" ON COMMIT DROP"在CREATE TEMP语句的末尾,即:

CREATE TEMP TABLE foo(bar INT)ON COMMIT DROP;

无论如何,你的两个函数将在一个事务中执行,所以当你从outer_function调用inner_function时,你将处于同一个事务中,而PostgreSQL将检测到" tempTable"已存在于当前会话中,并将其放入" inner_function"然后再创造......

答案 1 :(得分:0)

  

这是打算吗?

是的,这些是数据库中的表,类似于永久表。

它们存在于特殊模式中,并在会话或事务结束时自动删除。如果创建一个与永久表同名的临时表,则必须在永久表前面加上其模式名称,以便在临时表存在时引用它。

如果要模拟SQL Server实现,则可以考虑为临时表使用特定前缀。