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,
To return set of composite type from plpgsql function you should:
setof composite_type
, 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;
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;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With