0

Below is a dummy test query that correctly creates a text version of a SQL query I seek to execute

select string_agg(format($q$SELECT c1,c2 FROM %I.parcel t 
                JOIN bounds b
                    ON 1=1
                $q$, shm), e'UNION\n') as sql
                FROM unnest(array['a','b','c']) as shm 

this outputs

SELECT C1,C2 FROM a.parcel t 
                JOIN bounds b
                    ON 1=1
                UNION
SELECT C1,C2 FROM b.parcel t 
                JOIN bounds b
                    ON 1=1
                UNION
SELECT C1,C2 FROM c.parcel t 
                JOIN bounds b
                    ON 1=1
                

which is correct. What I want to do is actually run the above query. I tried un-nesting it but that did not work. Again this is test data so the contents of the query do not matter

I know I can do this

DO
$do$
BEGIN
execute string_agg(format($q$SELECT c1,c2 FROM %I.parcel t 
                    JOIN bounds b
                        ON 1=1
                    $q$, shm), e'UNION\n') as sql
                    FROM unnest(array['a','b','c']) as shm 
END
$do$;

but its not actually running the SQL text

2 Answers 2

1

The query in the DO block is run but its results are discarded.

As mentioned in the doc

The code block is treated as though it were the body of a function with no parameters, returning void. It is parsed and executed a single time.

If you expected the results returned in a single pass as if you had submitted the generated SQL directly, it's not possible with PostgreSQL.

You may either:

  1. make your SQL client retrieve the SQL text and resend it immediately as a query (\gexec in psql does that automatically)
  2. or, inside the code block, feed the results to variables with SELECT INTO or to a temporary table or wherever they fit for further processing.
  3. or, open a refcursor with a hard-coded name in the DO block to browse the results of the query with a FETCH, client-side.
Sign up to request clarification or add additional context in comments.

Comments

0

I ended getting what I wanted from this -- looped through the select statement and EXECUTE that SQL text into a variable that gets returned

CREATE OR REPLACE FUNCTION test()
RETURNS bytea as
$$
DECLARE
  stmt text;
  result bytea;
BEGIN
  FOR stmt IN
    select string_agg(format($q$SELECT c1,c2 FROM %I.parcel t 
                    JOIN bounds b
                        ON 1=1
                    $q$, shm), e'UNION\n') as sql
                    FROM unnest(array['a','b','c']) as shm 
  LOOP
 
    EXECUTE stmt into result;
    return result;
  END LOOP;
END;
$$
LANGUAGE plpgsql VOLATILE;

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.