Pertanyaan Postgres berfungsi mengembalikan satu catatan sementara saya memiliki banyak catatan?


Saya memiliki banyak catatan yang dikembalikan oleh permintaan sederhana saya tetapi ketika saya menggunakan fungsi itu hanya memberi saya rekaman pertama,

pertama saya membuat tipe data saya sendiri menggunakan,

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

dan fungsi saya adalah,

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;

dalam fungsi ini saya mengembalikan my_type yang hanya mengembalikan baris pertama cara mengembalikan lebih dari satu baris,


4
2018-05-27 11:50


asal


Jawaban:


Untuk mengembalikan set tipe komposit dari fungsi plpgsql Anda harus:

  • mendeklarasikan kembali tipe fungsi sebagai setof composite_type,
  • menggunakan return query (atau return next) petunjuk (dokumentasi).

Saya telah mengedit kode Anda hanya dalam konteks mengubah jenis kembalian (ini hanyalah contoh):

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
2018-05-27 12:26



Anda harus kembali setof my_type dan jika saya mengerti apa yang Anda inginkan, Anda tidak perlu SQL dinamis

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;

Dan jika Anda melewatkan parameter, itu bisa berupa sql biasa

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;

2
2018-05-27 12:26