6

I'm trying to create a function which runs an SQL query on multiple tables and outputs the resulting table from the query. The resulting table will have multiple rows. I'm having a lot of difficulty with this and I've read posts which suggest using RETURN NEXT but I haven't been able to get that to work either. From what I understand RECORD can be used because it takes the values of the data fed into it. Here is my code so far:

CREATE OR REPLACE FUNCTION
    most_docs()
RETURNS
    SETOF RECORD
AS $$
DECLARE
    result RECORD;
BEGIN
    CREATE VIEW MOSTDOC AS
    SELECT P.country, COUNT(P.country) AS cnt
    FROM Producer P, Movie M, ProducerMovie PM
    WHERE M.title = PM.title
    AND M.year = PM.year
    AND P.name = PM.name
    AND M.genre = 'Documentary'
    GROUP BY P.country;

    SELECT DISTINCT M.country INTO result
    FROM MOSTDOC M
    WHERE M.cnt = (SELECT MAX(M.cnt)
    FROM MOSTDOC M);

    RETURN result;
END;
$$ LANGUAGE plpgsql;

Any help would be much appreciated. Thanks.

---------- Word in Progress code

CREATE OR REPLACE FUNCTION
    most_docs()
RETURNS
    SETOF RECORD
AS $$
DECLARE
result RECORD
BEGIN
    CREATE VIEW MOSTDOC AS
    SELECT P.country, COUNT(P.country) AS cnt
    FROM Producer P, Movie M, ProducerMovie PM
    WHERE M.title = PM.title
    AND M.year = PM.year
    AND P.name = PM.name
    AND M.genre = 'Documentary'
    GROUP BY P.country;

    RETURN QUERY SELECT DISTINCT M.country
    FROM MOSTDOC M
    WHERE M.cnt = (SELECT MAX(M.cnt)
    FROM MOSTDOC M);
END;
$$ LANGUAGE plpgsql;

2 Answers 2

3

If i understand your problem correctly, your'e trying to do something like this (for functions that return setof i always use types)

CREATE TYPE frt_test_type AS
   (
    country character varying,
    cnt integer,
    country character varying); /* types may vary */

CREATE OR REPLACE FUNCTION
  RETURNS SETOF frt_test_type AS
$BODY$DECLARE r record;
BEGIN
  for r in     SELECT P.country, COUNT(P.country) AS cnt, 
FROM Producer P, Movie M, ProducerMovie PM
WHERE M.title = PM.title
AND M.year = PM.year
AND P.name = PM.name
AND M.genre = 'Documentary'
GROUP BY P.country;
  loop
      return next r; 
  end loop;
  return; 
END;$BODY$
  LANGUAGE 'plpgsql'
Sign up to request clarification or add additional context in comments.

Comments

0

According to this answer, what you need is:

RETURN QUERY SELECT DISTINCT......

5 Comments

Does this mean that I don't need to declare a variable result RECORD and delete the corresponding RETURN result line? If I do this I get "a column definition list is required for fuctions returning 'record'"
I think you still need result RECORD but can leave out the RETURN result
Hmm I'm getting the same error. I updated the question to show the new code. If it makes a difference the way I'm calling the function is SELECT * most_docs(). Is this correct syntax?
I believe SELECT * FROM most_docs() is correct. You may have to cast M.country to the proper data type in the RETURN QUERY line like: M.country::text or whatever the type is.
How can I put that in correct syntax. RETURN QUERY SELECT DISTINCT M.country M.country%TYPE ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.