简体   繁体   中英

Passing more than one row (query result) into a function

I have a SELECT from a function (with ordinary, not SETOF argument). However, I would like to call the function multiple times within the query (and then to aggregate the results), feeding it with a CTE.

Some (example) code:

CREATE TYPE MY_TYPE AS ( a integer, b integer );

CREATE OR REPLACE FUNCTION foo( foobar INTEGER ) 
RETURNS MY_TYPE AS $$
BEGIN
  -- do something, return MY_TYPE
END;  
$$ LANGUAGE plpgsql;

WITH x AS (
  SELECT a FROM bar WHERE b = 1
)
SELECT min(a) FROM foo( (SELECT a FROM x) ) f

This doesn't work, I get following error message:

ERROR:  more than one row returned by a subquery used as an expression

Now I wonder how to rewrite the query. I could loop over the CTE results, then call the function with one input value at a time, store results in a column, and finally find the minimum - this feels clumsy and should be quite slow. Another approach would be to wrap my function in another, set-returning and with array parameter. But this just pushes the problem away: I don't know how to simply wrap it.

What seems fine is to rewrite the function to the SETOF form. Still, this is a workaround, and learning how to call ordinary functions with more than one row returned by a query (if it is possible) would be better.

Try this:

SELECT min(f.a)
  FROM bar  
  CROSS JOIN foo(bar.a) f
  WHERE bar.b = 1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM