这就是我现在正在做的,它工作正常,但必须有一个更好的方法来做到这一点.
CREATE OR REPLACE FUNCTION my_func() RETURNS TABLE ( "a" integer,"b" varchar ) AS $$ DECLARE r record; BEGIN CREATE TEMP TABLE tmp_t ( "a" integer,"b" varchar ); -- Define the tuple structure of r by SELECTing an empty row into it. -- Is there a more straight-forward way of doing this? SELECT * INTO r FROM tmp_t; -- Now I can assign values to the record. r.a := at.something FROM "another_table" at WHERE at.some_id = 1; -- A related question is - how do I return the single record 'r' from -- this function? -- This works: RETURN QUERY SELECT * FROM tmp_t; -- But this doesn't: RETURN r; -- ERROR: RETURN cannot have a parameter in function returning set END; $$LANGUAGE plpgsql;
SETOF
values with syntax for returning a single row or value.
— A related question is – how do I return the single record ‘r’ from
使用RETURNS TABLE声明函数时,必须在正文中使用RETURN NEXT返回行(或标量值).如果你想使用一个记录变量,它必须匹配返回类型.请进一步参考代码示例.
返回单个值或行
如果您只想返回单行,则不需要未定义类型的记录. @Kevin已经展示了两种方式.我将添加一个带OUT参数的简化版本:
CREATE OR REPLACE FUNCTION my_func(OUT a integer,OUT b text) AS $func$ BEGIN a := ...; b := ...; END $func$LANGUAGE plpgsql;
你甚至不需要添加RETURN;在函数体中,声明的OUT参数的值将在函数末尾自动返回 – 对于尚未分配的任何参数,为NULL.
而且您不需要声明RETURNS RECORD,因为OUT参数已经清楚了.
返回一组行
如果您确实想要返回多行(包括0或1行的可能性),您可以将返回类型定义为RETURNS …
> SETOF some_type,其中some_type可以是任何已注册的标量或复合类型.
> TABLE(col1 type1,col2 type2) – ad-hoc行类型定义.
> SETOF记录加上OUT参数来定义列名和类型.
100%相当于RETURNS TABLE.
> SETOF记录无需进一步定义.但是返回的行是未定义的,您需要在每次调用时都包含一个列定义列表(参见示例).
The manual about the record type:
Record variables are similar to row-type variables,but they have no
predefined structure. They take on the actual row structure of the
row they are assigned during a SELECT or FOR command.
还有更多,请阅读手册.
您可以在不指定已定义类型的情况下使用记录变量,甚至可以返回此类未定义的记录:
CREATE OR REPLACE FUNCTION my_func() RETURNS SETOF record AS $func$ DECLARE r record; BEGIN r := (1::int,'foo'::text); RETURN NEXT r; -- works with undefined record r := (2::int,'bar'::text); RETURN NEXT r; END $func$LANGUAGE plpgsql;
呼叫:
SELECT * FROM my_func() AS x(a int,b text);
但这非常难以处理,因为您必须为每次调用提供列定义列表.它通常可以用更优雅的东西代替:
>如果您在创建函数时知道类型,请立即声明它(RETURNS TABLE或朋友).
CREATE OR REPLACE FUNCTION my_func() RETURNS SETOF tbl_or_type AS $func$ DECLARE r tbl_or_type; BEGIN SELECT INTO tbl_or_type * FROM tbl WHERE id = 10; RETURN NEXT r; -- type matches SELECT INTO tbl_or_type * FROM tbl WHERE id = 12; RETURN NEXT r; -- Or simpler: RETURN QUERY SELECT * FROM tbl WHERE id = 14; END $func$LANGUAGE plpgsql;
>如果你知道函数调用时的类型,使用polymorphic types有更优雅的方法:
Refactor a PL/pgSQL function to return the output of various SELECT queries
你的问题不清楚你究竟需要什么.