In continuing from a previous case that was assisted by @Erwin Brandstetter and @Craig Ringer, I have fixed my code to become as follows. Note, that my function myresult()
outputs now text
, and not a table (as indeed, as was pointed out in the former case, there is no point in outputting a table object, since we would need to define all its columns ahead, which basically defies the entire purpose):
CREATE OR REPLACE FUNCTION myresult(mytable text, myprefix text)
RETURNS text AS
$func$
DECLARE
myoneliner text;
BEGIN
SELECT INTO myoneliner
'SELECT '
|| string_agg(quote_ident(column_name::text), ',' ORDER BY column_name)
|| ' FROM ' || quote_ident(mytable)
FROM information_schema.columns
WHERE table_name = mytable
AND column_name LIKE myprefix||'%'
AND table_schema = 'public'; -- schema name; might be another param
RAISE NOTICE 'My additional text: %', myoneliner;
RETURN myoneliner;
END
$func$ LANGUAGE plpgsql;
Call:
select myresult('dkj_p_k27ac','enri');
Upon running the above procedure I get a text string, which is basically a query. I'll refer to it up next as 'oneliner-output', just for simplicity.
The 'oneline-output' looks as follows (I just copy/paste it from the one output cell that I've got into here):
"SELECT enrich_d_dkj_p_k27ac,enrich_lr_dkj_p_k27ac,enrich_r_dkj_p_k27ac FROM dkj_p_k27ac"
- Note that the double quotes from both sides of the statement were part of the
myresult()
output. I didn't add them.
I understand much better now the problematic idea of thinking to construct a single function that would both create the 'oneliner-output' AND execute it. I am able to copy/paste the 'oneliner-output' into a new Postgres query window and execute it as a normal query just fine, receiving the desired columns and rows in my Data Output window.
I would like, however, to automate this step, so to avoid the copy/paste step. Is there a way in Postgres to use the text
output (the 'oneliner-output') that I receive from myresult()
function, and execute it? Can a second function be created that would receive the output of myresult()
and use it for executing a query?
Along these lines, while I know that the following scripting (here below) works and actually outputs exactly the desired columns and rows:
-- DEALLOCATE stmt1; -- use this line after the first time 'stmt1' was created
prepare stmt1 as SELECT enrich_d_dkj_p_k27ac,enrich_lr_dkj_p_k27ac,enrich_r_dkj_p_k27ac FROM dkj_p_k27ac;
execute stmt1;
I was thinking maybe something like the following scripting could potentially work, after doing the correct tweaking? Not sure how though.
prepare stmt1 as THE_OUTPUT_OF_myresult();
execute stmt1;
Attempt with a refcursor
CREATE OR REPLACE FUNCTION show_mytable(ref refcursor) RETURNS refcursor AS $$
BEGIN
OPEN ref FOR SELECT enrich_d_dkj_p_k27ac,enrich_lr_dkj_p_k27ac,enrich_r_dkj_p_k27ac FROM dkj_p_k27ac; -- Open a cursor
RETURN ref; -- Return the cursor to the caller
END;
$$ LANGUAGE plpgsql;
Call:
BEGIN;
SELECT show_mytable('roy');
FETCH ALL IN "roy";
This procedure, actually works and spits out the desired columns and rows, and yet again, I have to provide the exact SELECT statement.
I basically would like to be able and provide it instead as the output of my myresult()
function. Something like this:
CREATE OR REPLACE FUNCTION show_mytable(ref refcursor) RETURNS refcursor AS $$
BEGIN
OPEN ref FOR myresult(); -- Open a cursor
RETURN ref; -- Return the cursor to the caller
END;
$$ LANGUAGE plpgsql;
Call:
BEGIN;
SELECT show_mytable('roy');
FETCH ALL IN "roy";
See Question&Answers more detail:
os