Postgres function returning one record while I have many records?

元气小坏坏 提交于 2019-12-04 03:54:38

问题


I have many records which my simple query returning but when i use function it just gives me first record,

firstly i create my own data type using,

CREATE TYPE my_type (usr_id integer , name varchar(30));

and my function is,

CREATE OR REPLACE function test() returns my_type as $$
    declare rd varchar := '21';
    declare personphone varchar := NULL;
    declare result my_type;
    declare SQL VARCHAR(300):=null; 
DECLARE
    radiophone_clause text = '';

BEGIN        
    IF rd IS NOT NULL then
        radiophone_clause = 'and pp.radio_phone = '|| quote_literal(rd);
    END IF;

    IF personphone IS NOT NULL then      
        radiophone_clause = radiophone_clause|| 'and pp.person_phone = '|| quote_literal(personphone);
    END IF;
    radiophone_clause = substr(radiophone_clause, 5, length(radiophone_clause)- 4);

     EXECUTE format('select pt.id,pt.name from product_template pt inner join product_product pp on pt.id=pp.id where %s ;', radiophone_clause) into result.id,result.name ;
    return result;
END;
$$ LANGUAGE plpgsql;

in this function i am returning my_type which return only first row how to return more then one row,


回答1:


To return set of composite type from plpgsql function you should:

  • declare function's return type as setof composite_type,
  • use return query (or return next) instruction (documentation).

I have edited your code only in context of changing return type (it is an example only):

DROP function test();   -- to change the return type one must drop the function

CREATE OR REPLACE function test() 
-- returns my_type as $$
returns setof my_type as $$                    -- (+)
    declare rd varchar := '21';
    declare personphone varchar := NULL;
--    declare result my_type;
--    declare SQL VARCHAR(300):=null; 
DECLARE
    radiophone_clause text = '';

BEGIN        
    IF rd IS NOT NULL then
        radiophone_clause = 'and pp.radio_phone = '|| quote_literal(rd);
    END IF;

    IF personphone IS NOT NULL then      
        radiophone_clause = radiophone_clause|| 'and pp.person_phone = '|| quote_literal(personphone);
    END IF;
    radiophone_clause = substr(radiophone_clause, 5, length(radiophone_clause)- 4);

    RETURN QUERY                               -- (+)
    EXECUTE format('select pt.id,pt.name from product_template pt inner join product_product pp on pt.id=pp.id where %s ;', radiophone_clause)
    ;                                          -- (+)
--    into result.id,result.name;
--    return result;
END;
$$ LANGUAGE plpgsql;



回答2:


You need to return setof my_type and if I understand what you want you don't need dynamic SQL

create or replace function test() returns setof my_type as $$
declare
    rd varchar := '21';
    personphone varchar := NULL;
begin
    return query
    select pt.id, pt.name
    from
        product_template pt
        inner join
        product_product pp using(id)
    where
        (pp.radio_phone = rd or rd is null)
        and
        (pp.person_phone = personphone or personphone is null)
    ;
end;
$$ language plpgsql;

And if you pass the parameters it can be plain sql

create or replace function test(rd varchar, personphone varchar)
returns setof my_type as $$
    select pt.id, pt.name
    from
        product_template pt
        inner join
        product_product pp using(id)
    where
        (pp.radio_phone = rd or rd is null)
        and
        (pp.person_phone = personphone or personphone is null)
    ;
$$ language sql;


来源:https://stackoverflow.com/questions/23888675/postgres-function-returning-one-record-while-i-have-many-records

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!