无法在 Postgres 函数中删除温度 table:"being used by active queries in this session"
Can't drop temp table in Postgres function: "being used by active queries in this session"
现在预计将接收一个名为 waypoints
的 table 并跟随函数体。
drop function if exists everything(waypoints);
create function everything(waypoints) RETURNS TABLE(node int, xy text[]) as $$
BEGIN
drop table if exists bbox;
create temporary table bbox(...);
insert into bbox
select ... from waypoints;
drop table if exists b_spaces;
create temporary table b_spaces(
...
);
insert into b_spaces
select ...
drop table if exists b_graph; -- Line the error flags.
create temporary table b_graph(
...
);
insert into b_graph
select ...
drop table if exists local_green;
create temporary table local_green(
...
);
insert into local_green
...
with aug_temp as (
select ...
)
insert into b_graph(source, target, cost) (
(select ... from aug_temp)
UNION
(select ... from aug_temp)
);
return query
with
results as (
select id1, ... from b_graph -- The relation being complained about.
),
pkg as (
select loc, ...
)
select id1, array_agg(loc)
from pkg
group by id1;
return;
END;
$$ LANGUAGE plpgsql;
这个returnscannot DROP TABLE b_graph because it is being used by active queries in this session
我该如何解决这个问题?
错误信息很明显,你不能删除正在使用的临时文件table。
您可以通过添加 ON COMMIT DROP
:
来避免该问题
- Temporary table and loops in a function
但是,这可能更简单。如果您 不需要 所有这些温度 table 开始(我怀疑),您可以将它们全部替换为 CTE(或者其中大部分可能甚至更便宜子查询)并简化为一个大查询。可以是 plpgsql 或只是 SQL:
CREATE FUNCTION everything(waypoints)
RETURNS TABLE(node int, xy text[]) AS
$func$
WITH bbox AS (SELECT ... FROM waypoints) -- not the fct. parameter!
, b_spaces AS (SELECT ... )
, b_graph AS (SELECT ... )
, local_green AS (SELECT ... )
, aug_temp AS (SELECT ... )
, b_graph2(source, target, cost) AS (
SELECT ... FROM b_graph
UNION ALL -- guessing you really want UNION ALL
SELECT ... FROM aug_temp
UNION ALL
SELECT ... FROM aug_temp
)
, results AS (SELECT id1, ... FROM b_graph2)
, pkg AS (SELECT loc, ... )
SELECT id1, array_agg(loc)
FROM pkg
GROUP BY id1
$func$ LANGUAGE sql;
视图仅存储查询 ("the recipe"),而不是实际结果值 ("the soup")。
通常使用 CTE 比创建临时 tables 更便宜。
在查询 中派生了 table,按它们的典型整体性能排序(涉及索引的特殊情况除外)。从慢到快:
CREATE TABLE
CREATE UNLOGGED TABLE
CREATE TEMP TABLE
CTE
subquery
UNION
会尝试折叠重复的行。通常,人们真的想要 UNION ALL
,它只是附加行。更快,并且不会尝试删除重复项。
现在预计将接收一个名为 waypoints
的 table 并跟随函数体。
drop function if exists everything(waypoints);
create function everything(waypoints) RETURNS TABLE(node int, xy text[]) as $$
BEGIN
drop table if exists bbox;
create temporary table bbox(...);
insert into bbox
select ... from waypoints;
drop table if exists b_spaces;
create temporary table b_spaces(
...
);
insert into b_spaces
select ...
drop table if exists b_graph; -- Line the error flags.
create temporary table b_graph(
...
);
insert into b_graph
select ...
drop table if exists local_green;
create temporary table local_green(
...
);
insert into local_green
...
with aug_temp as (
select ...
)
insert into b_graph(source, target, cost) (
(select ... from aug_temp)
UNION
(select ... from aug_temp)
);
return query
with
results as (
select id1, ... from b_graph -- The relation being complained about.
),
pkg as (
select loc, ...
)
select id1, array_agg(loc)
from pkg
group by id1;
return;
END;
$$ LANGUAGE plpgsql;
这个returnscannot DROP TABLE b_graph because it is being used by active queries in this session
我该如何解决这个问题?
错误信息很明显,你不能删除正在使用的临时文件table。
您可以通过添加 ON COMMIT DROP
:
- Temporary table and loops in a function
但是,这可能更简单。如果您 不需要 所有这些温度 table 开始(我怀疑),您可以将它们全部替换为 CTE(或者其中大部分可能甚至更便宜子查询)并简化为一个大查询。可以是 plpgsql 或只是 SQL:
CREATE FUNCTION everything(waypoints)
RETURNS TABLE(node int, xy text[]) AS
$func$
WITH bbox AS (SELECT ... FROM waypoints) -- not the fct. parameter!
, b_spaces AS (SELECT ... )
, b_graph AS (SELECT ... )
, local_green AS (SELECT ... )
, aug_temp AS (SELECT ... )
, b_graph2(source, target, cost) AS (
SELECT ... FROM b_graph
UNION ALL -- guessing you really want UNION ALL
SELECT ... FROM aug_temp
UNION ALL
SELECT ... FROM aug_temp
)
, results AS (SELECT id1, ... FROM b_graph2)
, pkg AS (SELECT loc, ... )
SELECT id1, array_agg(loc)
FROM pkg
GROUP BY id1
$func$ LANGUAGE sql;
视图仅存储查询 ("the recipe"),而不是实际结果值 ("the soup")。
通常使用 CTE 比创建临时 tables 更便宜。
在查询 中派生了 table,按它们的典型整体性能排序(涉及索引的特殊情况除外)。从慢到快:
CREATE TABLE
CREATE UNLOGGED TABLE
CREATE TEMP TABLE
CTE
subquery
UNION
会尝试折叠重复的行。通常,人们真的想要 UNION ALL
,它只是附加行。更快,并且不会尝试删除重复项。