在一些恶化之后,当一个函数调用另一个函数时,我发现(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
答案 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实现,则可以考虑为临时表使用特定前缀。