这是我的功能:
CREATE OR REPLACE FUNCTION getAllFoo()
RETURNS SETOF "TraderMonthOutstanding" AS
$BODY$
DECLARE
r record;
BEGIN
FOR r IN (select * from "TraderMonthOutstanding"
where "TraderId"=1 and "IsPaid"=false)
LOOP
RETURN NEXT r.TraderId;
END LOOP;
RETURN;
END
$BODY$
LANGUAGE 'plpgsql' ;
我只想从这个循环中TraderId
但是我无法得到它,因为它给了我一个错误。
我做错了什么?
答案 0 :(得分:1)
您声明getAllFoo()
将RETURNS SETOF "TraderMonthOutstanding"
(一组具有表格TraderMonthOutstanding
结构的行)但您RETURN NEXT r.TraderId
(单个字段)。
您需要将声明的返回类型更改为RETURNS SETOF "TraderMonthOutstanding".TraderId%TYPE
或RETURN NEXT r
。
答案 1 :(得分:1)
您应该返回setof integer
或setof TraderMonthOutstanding".TraderId%TYPE
。
或者更改setof record
并返回next r
或事件setof TraderMonthOutstanding
并将r声明为TraderMonthOutstanding行类型而不是匿名记录。
更好的是,这似乎是一种情况,您应该创建一个视图以避免完全使用函数的开销:
create view getAllFoo as
select *
from "TraderMonthOutstanding"
where "TraderId"=1 and "IsPaid"=false;
select * from getAllFoo;
如果你没有做任何有用的事情,那么在函数中循环遍历这样的集合通常是很糟糕的做法。 (虽然我认为真正的人正在做某事。)
最后,如果你真的想在函数中使用它,请注意你可以return query
完全避免循环:
return query
select *
from "TraderMonthOutstanding"
where "TraderId"=1 and "IsPaid"=false;
答案 2 :(得分:1)
@Igor和@Denis说的是什么 如果你实际上需要循环,这在你的例子中并不明显,它会像这样工作:
CREATE OR REPLACE FUNCTION get_all_foo()
RETURNS SETOF "TraderMonthOutstanding"."TraderId"%TYPE AS
$func$
DECLARE
r "TraderMonthOutstanding"; -- use the well known type
BEGIN
FOR r IN
SELECT * FROM "TraderMonthOutstanding"
WHERE "TraderId" = 1
AND "IsPaid" = FALSE -- no parentheses needed
LOOP
-- do whatever necessitates a loop
RETURN NEXT r."TraderId";
END LOOP;
RETURN;
END
$func$ LANGUAGE plpgsql;
不要引用语言名称plpgsql
。它是一个标识符,而不是文字。目前的Postgres容忍它,但在未来的版本中可能会被淘汰。
我建议不要在Postgres中使用CaMeL案例标识符 。如果你引用一些,而不是其他人,则更少。这是一个LoaDed Footgun。 Read the manual about identifiers.
由于您已经知道您要使用的记录类型,因此请不要降级为匿名record
,请使用众所周知的类型开头: “TraderMonthOutstanding”。
就像您已经被告知的那样,RETURN
返回的类型必须与您声明的RETURNS
相匹配。由于您want only TraderId
,请相应地调整RETURNS
。如果要从现有表派生它,可以使用显示的语法。 Details in the manual.或者您可以插入实际类型。像integer
或其他什么。
由于您在制作表格时似乎一直使用双引号CaMeL案例名称,因此您必须继续使用它们:双引号 - 即使是函数体中的派生类型:
RETURN NEXT r."TraderId";
看看我对“LoaDed Footgun”的意思?