PostgreSQL: отображение результата с использованием переменной типа RECORD в функции

Я передаю имя столбца и имя таблицы в качестве параметра для функции динамического запроса, как показано ниже в примере.

Проблема: при выполнении запроса "SELECT" в функции отображается только структура таблицы, а не строки.

Пример:

--Стол

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
 );

--Вставка нескольких строк

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');

--Функция

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; 

--Вызов функции

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)

person Meem    schedule 01.04.2014    source источник


Ответы (1)


Вы должны вернуть результаты внутри функции. (если это не RETURNS VOID), например

RETURN QUERY EXECUTE sqlq;

И вы должны правильно экранировать имена столбцов, напр. с помощью функции format(), как

RETURN QUERY EXECUTE format('SELECT "col1", %I FROM %I', 'col2', 'test1');
person pozs    schedule 01.04.2014
comment
Большой! Большое спасибо. - person Meem; 01.04.2014
comment
Дезинфекция динамического ввода обязательна, но в данном случае это относится только к имени таблицы (в исходном примере ответ отличается). Двойные кавычки вокруг "col1" и обработка col2 здесь бесполезны - оба являются жестко закодированными, допустимыми именами в нижнем регистре. Подробнее. - person Erwin Brandstetter; 02.04.2014
comment
@ErwinBrandstetter это всего лишь пример того, как использовать функцию форматирования для этой цели. - person pozs; 02.04.2014