Thông báo lỗi khá rõ ràng, bạn không thể thả bảng tạm thời khi nó đang được sử dụng.
Bạn có thể tránh được sự cố bằng cách thêm ON COMMIT DROP
:
Tuy nhiên, điều này có thể đơn giản hơn. Nếu bạn không cần tất cả các bảng tạm thời đó để bắt đầu (mà tôi nghi ngờ), bạn có thể thay thế tất cả chúng bằng CTE (hoặc hầu hết chúng thậm chí có thể bằng các truy vấn con rẻ hơn) và đơn giản hóa thành một truy vấn lớn. Có thể là plpgsql hoặc chỉ 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;
Chế độ xem chỉ lưu trữ một truy vấn ("công thức"), không phải các giá trị kết quả thực tế ("súp").
Thông thường, việc sử dụng CTE thay vì tạo bảng tạm thời sẽ rẻ hơn.
Bảng gốc trong truy vấn , được sắp xếp theo hiệu suất tổng thể điển hình của chúng (ngoại lệ cho các trường hợp đặc biệt liên quan đến chỉ mục). Từ chậm đến nhanh:
CREATE TABLE
CREATE UNLOGGED TABLE
CREATE TEMP TABLE
CTE
subquery
UNION
sẽ cố gắng gấp các hàng trùng lặp. Thông thường, mọi người thực sự muốn UNION ALL
, chỉ nối các hàng. Nhanh hơn và không cố gắng loại bỏ các vi phạm.