0

I am passing column name and table name as parameter to function for dynamic query as shown below in example.

Problem: While executing "SELECT" query within function, it only displaying the structure of the table not rows.

Example:

--Table

create table test1
(
   rollno integer,
   fname text,
   lname text,
   age integer,
   branch text,
   phno integer,
   email text,
   address text,
   city text,
   state text,
   country text
 );

--Inserting some rows

insert into tes1 values(1,'aaa','bbb',25,'CS',1234567890,'[email protected]','sector1','xyz','zyx','yxz');

insert into tes1 values(2,'zzz','xxx',25,'EE',987654321,'[email protected]','sector2','uvw','wvu','vuw');

--Function

create or replace function fun1(colB text,vname varchar)
returns setof record as
$body$
declare 
       str text;
       grp text;
       addi text;
       sqlq varchar;
       tname varchar;
begin
       if colB='fname' then
         str:='fname';
         grp:='rollno'||','||'fname';
         addi:='city'||','||'state'||','||'country';
         tname:=vname;

       elsif colB='lname' then
         str:='lname';
         grp:='rollno'||','||'lname';
         addi:='city'||','||'state'||','||'country';
         tname:=vname;
       end if;

   raise info '%',str;
   raise info '%',grp;
   raise info '%',addi;
   raise info '%',vname;
   raise info '%',tname;

   sqlq:='select rollno,'||str||',age,branch,'||addi||' from '|| tname;
   raise info '%',sqlq;
   execute sqlq;    

end;
$body$
language plpgsql; 

--Function calling

select * from fun1('lname','test1') as ("rollno" integer,"lname" text,
"age" integer,"branch" text,"city" text,"state" text,"country" text);

INFO:  lname
INFO:  rollno,lname
INFO:  city,state,country
INFO:  tes1
INFO:  tes1
INFO:  select rollno,lname,age,branch,city,state,country from tes1
rollno | lname | age | branch | city | state | country
--------+-------+-----+--------+------+-------+---------
(0 rows)

1 Answer 1

2

You must return with the results inside a function (unless it's RETURNS VOID), like

RETURN QUERY EXECUTE sqlq;

And, you should properly escape the column names, f.ex. with the format() function, like

RETURN QUERY EXECUTE format('SELECT "col1", %I FROM %I', 'col2', 'test1');
Sign up to request clarification or add additional context in comments.

2 Comments

Sanitizing dynamic input is a must, but that only applies to the table name in this case (in the original example, the answer deviates). The double quotes around "col1" and the treatment of col2 serve no purpose here - both being hard coded, legal, lower-case names. More details.
@ErwinBrandstetter they are just an example, how to use format function for this purpose.

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.