更新(对于任何可能坚持这一点的人):
RETURN QUERY SELECT有效。其他地方写的是PERFORM与void结合使用。所以可能就是这个原因。感谢a_horse_with_no_name的链接。
问题是:
===============
以下是我尝试执行的功能:
CREATE OR REPLACE FUNCTION get_edition_data (date[], OUT fc_copies bigint, OUT cs_copies bigint, OUT ms_copies bigint)
RETURNS SETOF record AS $$
DECLARE
issue DATE;
BEGIN
FOREACH issue IN ARRAY $1
LOOP
SELECT
SUM (
CASE
WHEN (edition = 1 AND (period_from <= issue AND period_to >= issue)) THEN
copies
ELSE
0
END
),
SUM (
CASE
WHEN (edition = 2 AND (period_from <= issue AND period_to >= issue)) THEN
copies
ELSE
0
END
),
SUM (
CASE
WHEN (edition = 3 AND (period_from <= issue AND period_to >= issue)) THEN
copies
ELSE
0
END
)
FROM
public.subscriptions;
RETURN NEXT;
END LOOP;
RETURN;
END;
$$ LANGUAGE plpgsql;
我使用以下方法调用此函数:
SELECT public.get_edition_data(ARRAY[CAST ('2018-01-01' AS DATE)])
在这里我得到错误:
ERROR: query has no destination for result data
HINT: If you want to discard the results of a SELECT, use PERFORM instead.
CONTEXT: PL/pgSQL function get_edition_data(date[]) line 7 at SQL statement
我尝试使用postgres和S.O.的其他地方的例子来创建函数。在某些地方,我看到返回通常指向DECLARE中的记录变量。但在这里,我想循环通过我收到的日期。
-------更新
根据horse_with_no_name提供的内容,我浏览了链接,发现如果我用PERFORM替换SELECT,它可以在plpgsql中使用。现在错误已经沉默。但我没有输出。更新的代码是:
CREATE OR REPLACE FUNCTION get_edition_data (date[], OUT issue date, OUT fc_copies bigint, OUT cs_copies bigint, OUT ms_copies bigint)
RETURNS SETOF record AS $$
DECLARE
issue DATE;
BEGIN
FOREACH issue IN ARRAY $1
LOOP
RAISE NOTICE '%', issue;
PERFORM
issue,
SUM (
CASE
WHEN (edition = 1 AND (period_from <= issue AND period_to >= issue)) THEN
copies
ELSE
0
END
),
SUM (
CASE
WHEN (edition = 2 AND (period_from <= issue AND period_to >= issue)) THEN
copies
ELSE
0
END
),
SUM (
CASE
WHEN (edition = 3 AND (period_from <= issue AND period_to >= issue)) THEN
copies
ELSE
0
END
)
FROM
public.subscriptions;
RETURN NEXT;
END LOOP;
RETURN;
END;
$$ LANGUAGE plpgsql;
我现在正在使用以下内容查询:
SELECT * FROM public.get_edition_data(ARRAY[CAST ('2018-05-01' AS DATE),CAST ('2018-03-01' AS DATE)])
我没有记录,但它循环两次,我收到通知显示日期。
如果我删除所有函数并使用一个简单的select语句,日期硬编码如下:
SELECT SUM (
CASE
WHEN (edition = 1 AND (period_from <= '2018-03-01' AND period_to >= '2018-03-01')) THEN
copies
ELSE
0
END
),
SUM (
CASE
WHEN (edition = 2 AND (period_from <= '2018-03-01' AND period_to >= '2018-03-01')) THEN
copies
ELSE
0
END
),
SUM (
CASE
WHEN (edition = 3 AND (period_from <= '2018-03-01' AND period_to >= '2018-03-01')) THEN
copies
ELSE
0
END
)
FROM
public.subscriptions;
我得到以下内容:
sum | sum | sum |
3 | 0| 0 |
所以有记录和选择查询有效。