【发布时间】:2017-08-15 10:06:45
【问题描述】:
我在 PostgreSQL 9.2.9 中有一个 plpgsql 函数,它需要返回多个列。大多数列都来自一个表,所以我声明了虚拟表(这个术语正确吗?)rc 为:
rc "Sequence"%rowtype;
这很好用,除了我有额外的 2 列要添加到返回的数据中。如果我将上述声明替换为:
rc RECORD;
以及其他一些小的代码更改。但是我需要始终使用包含所有列定义的很长的SELECT 命令来明确调用该函数。
如何两全其美,即返回 "Sequence" 表的所有列并添加 2 个新列("AverageSED" 和 "avDailySED"),简单:
SELECT * FROM production1('2016-02-27 00:00:00','2016-03-11 00:00:00');
这是我使用 RECORD 类型的一般函数作为示例(为了便于阅读而删减)。
CREATE OR REPLACE FUNCTION production1(tme1 timestamp without time zone, tme2 timestamp without time zone, mn integer)
RETURNS SETOF record AS
$BODY$
DECLARE
-- Could possibly use (CREATE TYPE rcholder %rowtype) and use a function with a sub-function that then takes the rc RECORD and recasts it to type %rowtype. This would mean the column descriptor in the SELECT call could be dropped
rc record;
AverageSED Real;
avDailySED Real;
BEGIN
-- Calculate average of value from Log_Alpha table
SELECT AVG("logSED")::Real
FROM "Log_Alpha"
WHERE "logTime" >= tme1 AND "logTime" < tme2
INTO averageSED;
-- Select the required row from the sequence data table
FOR rc IN
SELECT *, AverageSED, avDailySED
FROM "Sequence"
WHERE "Sequence"."seqMinute" = mn AND "Sequence"."seqTime" >= tmeA AND "Sequence"."seqTime" <= tmeB
ORDER BY "Sequence"."seqTime"
LOOP
rc."seqTime" = rc."seqTime" - '1 day'::interval;
-- Use a subquery to calculate the average SED for all data for the day pertaining to this record date field
SELECT AVG("logSED")::Real into rc.avDailySED FROM "Log_Alpha"
WHERE "Log_Alpha"."logTime" >= rc."seqTime" and "Log_Alpha"."logTime" < (rc."seqTime" + '1 day'::interval);
RETURN NEXT rc ;-- (AverageSED,avDailySED);
END LOOP;
END
$BODY$
LANGUAGE plpgsql;
因此,由于"Sequence" 表中的所有可用列,此函数需要超过 1400 个字符的非常长的 SELECT 查询。
【问题讨论】:
-
不清楚是要缩短函数定义的
RETURNS子句还是函数体中的一些SQL 命令——还是两者兼而有之?提供您使用的完整功能的最小示例将非常有帮助(即使它还没有工作) -
我已经用我的缩写函数修改了这个问题。希望有帮助。我想要做的是将 SELECT 查询减少到我的问题中看到的,而不是有一个非常非常长的查询。 SELECT 查询最终嵌套在 Delphi 中用于 FastReport 报告目的,并且维护起来很麻烦。我真的不介意这是否会导致很长的 RETURNS 子句,尽管避免两者都是理想的。
-
tmeA,tmeB或tme1,tme2?请使功能一致。还有:Postgres 9.2.9? Urgently consider upgrading 至少到最新的次要版本。 -
您的问题似乎不是变量定义(
record变量工作正常),而是函数的返回类型(RETURNS子句)。你的问题在那里有点误导 - 或者这是基本的误解。 -
type records 或 %rowtype 对我有用,但是如果有意义的话,我一直未能找到一种方法来向 %rowtype “虚拟表”添加额外的列。如果匿名你的意思是我每列没有列名或数据类型,那么我认为这实际上是我试图用 RECORD 类型克服的问题,因为我必须在函数的查询中继续定义它。即 SELECT * FROM production1('2016-02-27 00:00:00','2016-03-11 00:00:00') AS table(col1 Integer, col2 Integer, col3 Real...等);
标签: sql postgresql function types plpgsql