PL/pgSQL 控制结构非 SETOF 问题

问题描述 投票:0回答:2

我有两个带有日期列(年、月、日以及三者的组合称为“标记”)和关联值(avalue)的表。我需要我的函数返回两个表之间的比率(在指定日期),在先前指定的限制日期之后返回固定值,并且如果该日期在数据中不可用(但低于限制),则它应选择输入后的第一个可用日期。

这是我写的代码:

CREATE OR REPLACE FUNCTION myfunction(theyear int, themonth int, theday int) RETURNS real AS '
    DECLARE
        foo tablenamea%rowtype;
    BEGIN
        IF ((theyear >= 2000) AND (themonth >= 6)) OR (theyear > 2000) THEN
            RETURN 0.1;
        ELSE 
            FOR foo IN SELECT (a.avalue/b.avalue) FROM tablenamea AS a, tablenameb AS b
            WHERE a.stamp = b.stamp AND a.year = theyear AND a.month = themonth AND a.day >= theday ORDER BY a.year, a.month, a.day
            LOOP
                RETURN NEXT foo;
            END LOOP;
            RETURN;
        END IF;
    END;
' LANGUAGE plpgsql;

这一直给我这个错误:

cannot use RETURN NEXT in a non-SETOF function
postgresql aggregate-functions
2个回答
1
投票

它告诉你应该返回一个 real,而不是 foo (这是一行)。

可能会返回

foo.somefield

另外,添加一个

limit 1
而不是
for
循环,因为我认为您只对第一行真正感兴趣。如果没有,请将其声明为返回,例如
table (ratio real)
并使用
return query


0
投票

我在下面遇到了同样的错误:

错误:无法在非 SETOF 函数中使用 RETURN NEXT

当我尝试创建具有

my_func()
类型的
RECORD
子句和
RETURNS
语句时,如下所示:
RETURN NEXT

因此,我将 
CREATE FUNCTION my_func() RETURNS RECORD AS $$ DECLARE -- ↑ ↑ ↑ row RECORD; BEGIN FOR row IN VALUES ('John', 'Smith'), ('David', 'Miller') LOOP RETURN NEXT row; -- Here END LOOP; END; $$ LANGUAGE plpgsql;

类型设置为

SETOF RECORD
子句,如下所示,然后我可以创建
RETURNS
而不会出现错误:
my_func()

然后,我可以在 
CREATE FUNCTION my_func() RETURNS SETOF RECORD AS $$ DECLARE -- ↑ ↑ ↑ ↑ ↑ ↑ row RECORD; BEGIN FOR row IN VALUES ('John', 'Smith'), ('David', 'Miller') LOOP RETURN NEXT row; END LOOP; END; $$ LANGUAGE plpgsql;

子句中调用

my_func()
,不会出现错误,如下所示:
FROM

或者,我将 
postgres=# SELECT * FROM my_func() AS (f_n TEXT, l_n TEXT); f_n | l_n -------+-------- John | Smith David | Miller (2 rows)

类型设置为

TABLE()
子句,然后将
RETURNS
f_n
参数设置为
FOR 语句
,而不是 l_n 局部变量,如下所示。 *如果将
row
局部变量设置为
row
语句,则会出现
错误
RETURN NEXT

然后,我可以毫无错误地调用
-- ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ CREATE FUNCTION my_func() RETURNS TABLE(f_n TEXT, l_n TEXT) AS $$ -- DECLARE -- row RECORD; BEGIN FOR f_n, l_n IN VALUES ('John', 'Smith'), ('David', 'Miller') LOOP RETURN NEXT /* row */; END LOOP; END; $$ LANGUAGE plpgsql;

,如下所示:

my_func()

*
文档

解释了postgres=# SELECT my_func(); my_func ---------------- (John,Smith) (David,Miller) (2 rows)

RETURN NEXT
    

© www.soinside.com 2019 - 2024. All rights reserved.