我有两个带有日期列(年、月、日以及三者的组合称为“标记”)和关联值(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
它告诉你应该返回一个 real,而不是 foo (这是一行)。
可能会返回
foo.somefield
。
另外,添加一个
limit 1
而不是 for
循环,因为我认为您只对第一行真正感兴趣。如果没有,请将其声明为返回,例如table (ratio real)
并使用 return query
。
我在下面遇到了同样的错误:
错误:无法在非 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
。