plpgsql - 不同形式的临时 table 以进行排序
plpgpsql - differents forms of temporary table in order to do a sort
我正在尝试优化一个具有 7 WITH
个临时 table 的函数,充当排序机制,从初始临时 table/sort 级联到下一个,直到最后一个,例如第 7 个临时 table/ sort.
Gist here: 这种代码必须禁止
我正在尝试用真正的临时 table 例如 CREATE TEMPORARY TABLE <table_name> AS SELECT col1 FROM another_table;
替换 WITH
排序。目的是提高性能,因为当前形式的查询非常非常慢。
这是我提议的更改
CREATE OR REPLACE FUNCTION report.get_sa001(
IN "date_D" timestamp without time zone,
IN "date_F" timestamp without time zone,
IN frequence integer)
RETURNS TABLE(
"Period_date" timestamp without time zone,
"Site" character varying,
"Customer_code" character varying,
"Internal_reference" character varying,
"InvoiceNumber" character varying,
"Value_in_currency" numeric,
"Value_in_EUR" numeric,
"Value_Budget_in_EUR" numeric,
"Selling_price_CUR" numeric,
"Selling_price_EUR" numeric,
"Currency_code" character varying,
"Selling_quantity" numeric,
"Variance_price_CUR" numeric,
"Variance_price_EUR" numeric,
"Variance_value_CUR" numeric,
"Variance_value_EUR" numeric,
"Selling_date" timestamp without time zone) AS
$BODY$
DECLARE
p_debut timestamp without time zone;
DECLARE
p_fin timestamp without time zone;
BEGIN
p_debut = dw.get_period_end("date_D", "frequence");
p_fin = dw.get_period_end("date_F", "frequence");
RETURN QUERY
CREATE TEMPORARY TABLE "dates_1" AS
SELECT
p_debut::date + n AS "date",
dw.period_frequency(p_debut::date + n) AS "frequency"
FROM generate_series(0, p_fin::date - p_debut::date) AS x(n)
WHERE (dw.period_frequency(p_debut::date + n) & frequence != 0);
SELECT * FROM "dates_1"; -- Thanks to Vao Tsun
END;
$BODY$
LANGUAGE plpgsql STABLE
COST 100
ROWS 1000;
函数的创建很好,但是当 运行 函数这样
SELECT * FROM report.get_sa001('2017-01-01'::date, '2017-01-31'::date, 32)
这就是我的
ERROR: cannot open query CREATE TABLE AS like cursor
État SQL :42P11
Contexte : fonction PL/pgsql report.get_sa001(timestamp without time zone,timestamp without time zone,integer), ligne 11 à RETURN QUERY
我试图用 SELECT * INTO TEMPORARY TABLE
替换 CREATE TEMPORARY TABLE
。创建又可以了,但是当 运行 它时我有同样的错误。
检查 SO 的存档,听起来 PLPGSQL 禁止使用临时 table(检查 here)。
如果您有任何想法,我们非常欢迎。
谢谢
在函数中使用create temporary table没有错:
t=# create or replace function so37() returns table (i int) as
$$
declare
begin
create temporary table a as select 2;
return query select * from a;
end;
$$ language plpgsql
;
CREATE FUNCTION
t=# select * from so37();
i
---
2
(1 row)
但必须维护它们,例如,在您当前的示例中,如果存在,则缺少 drop table,或者您应该插入而不是创建 table,因为如果不这样做,第二个 运行 将失败:
t=# select * from so37();
ERROR: relation "a" already exists
CONTEXT: SQL statement "create temporary table a as select 2"
PL/pgSQL function so37() line 4 at SQL statement
而且我相信 CTE 是在函数中创建临时 table 的更好选择...
我正在尝试优化一个具有 7 WITH
个临时 table 的函数,充当排序机制,从初始临时 table/sort 级联到下一个,直到最后一个,例如第 7 个临时 table/ sort.
Gist here: 这种代码必须禁止
我正在尝试用真正的临时 table 例如 CREATE TEMPORARY TABLE <table_name> AS SELECT col1 FROM another_table;
替换 WITH
排序。目的是提高性能,因为当前形式的查询非常非常慢。
这是我提议的更改
CREATE OR REPLACE FUNCTION report.get_sa001(
IN "date_D" timestamp without time zone,
IN "date_F" timestamp without time zone,
IN frequence integer)
RETURNS TABLE(
"Period_date" timestamp without time zone,
"Site" character varying,
"Customer_code" character varying,
"Internal_reference" character varying,
"InvoiceNumber" character varying,
"Value_in_currency" numeric,
"Value_in_EUR" numeric,
"Value_Budget_in_EUR" numeric,
"Selling_price_CUR" numeric,
"Selling_price_EUR" numeric,
"Currency_code" character varying,
"Selling_quantity" numeric,
"Variance_price_CUR" numeric,
"Variance_price_EUR" numeric,
"Variance_value_CUR" numeric,
"Variance_value_EUR" numeric,
"Selling_date" timestamp without time zone) AS
$BODY$
DECLARE
p_debut timestamp without time zone;
DECLARE
p_fin timestamp without time zone;
BEGIN
p_debut = dw.get_period_end("date_D", "frequence");
p_fin = dw.get_period_end("date_F", "frequence");
RETURN QUERY
CREATE TEMPORARY TABLE "dates_1" AS
SELECT
p_debut::date + n AS "date",
dw.period_frequency(p_debut::date + n) AS "frequency"
FROM generate_series(0, p_fin::date - p_debut::date) AS x(n)
WHERE (dw.period_frequency(p_debut::date + n) & frequence != 0);
SELECT * FROM "dates_1"; -- Thanks to Vao Tsun
END;
$BODY$
LANGUAGE plpgsql STABLE
COST 100
ROWS 1000;
函数的创建很好,但是当 运行 函数这样
SELECT * FROM report.get_sa001('2017-01-01'::date, '2017-01-31'::date, 32)
这就是我的
ERROR: cannot open query CREATE TABLE AS like cursor
État SQL :42P11
Contexte : fonction PL/pgsql report.get_sa001(timestamp without time zone,timestamp without time zone,integer), ligne 11 à RETURN QUERY
我试图用 SELECT * INTO TEMPORARY TABLE
替换 CREATE TEMPORARY TABLE
。创建又可以了,但是当 运行 它时我有同样的错误。
检查 SO 的存档,听起来 PLPGSQL 禁止使用临时 table(检查 here)。
如果您有任何想法,我们非常欢迎。
谢谢
在函数中使用create temporary table没有错:
t=# create or replace function so37() returns table (i int) as
$$
declare
begin
create temporary table a as select 2;
return query select * from a;
end;
$$ language plpgsql
;
CREATE FUNCTION
t=# select * from so37();
i
---
2
(1 row)
但必须维护它们,例如,在您当前的示例中,如果存在,则缺少 drop table,或者您应该插入而不是创建 table,因为如果不这样做,第二个 运行 将失败:
t=# select * from so37();
ERROR: relation "a" already exists
CONTEXT: SQL statement "create temporary table a as select 2"
PL/pgSQL function so37() line 4 at SQL statement
而且我相信 CTE 是在函数中创建临时 table 的更好选择...