Postgres-存儲過程 return 詳解


如果返回一個 數字或者字符 比較簡單,那么多行多列怎么辦呢,分為以下幾種情況  【東西很多,這里只做簡單列舉】

 

返回多行單列

又分為幾種方式

1. return next,用在 for 循環中

CREATE OR REPLACE FUNCTION funcname ( in_id integer)
RETURNS SETOF varchar as $$
DECLARE
    v_name varchar;
BEGIN
   for v_name in  ( (select  name  from test_result1  where id = in_id) union (select  name  from test_result2  where id = in_id) ) loop
     RETURN NEXT v_name;
   end loop;
   return;
END;
$$
LANGUAGE PLPGSQL;

注意

1. 循環外還有個 return

2. 需要實現聲明 v_name

 

2. return query,無需 for 循環

CREATE OR REPLACE FUNCTION funcname ( in_id integer)
RETURNS SETOF varchar as $$
DECLARE
    v_rec RECORD;
BEGIN
   return query  ( (select  name  from test_result1  where id = in_id) union (select  name  from test_result2  where id = in_id) );
   return;
END;
$$
LANGUAGE PLPGSQL;

注意:如果 返回類型為 setof,最好用如下方法

RETURN QUERY EXECUTE SQL

不要這么用

execute sql into  out;
return out;

 

返回多行多列

也有多種方式

1. 使用 return next 和  setof record ,需要 for 循環

CREATE OR REPLACE FUNCTION funcname ( in_id integer)
RETURNS SETOF RECORD as $$
DECLARE
    v_rec RECORD; 
BEGIN
   for v_rec in  ( (select id , name  from test_result1  where id = in_id) union (select id , name  from test_result2  where id = in_id) )loop
    RETURN NEXT v_rec;
   end loop;
   return;
END;
$$
LANGUAGE PLPGSQL;

注意

1. 讀取表的整行數據時才能用 record

2. 如果讀取的數據不是整行,需要自定義 復合數據類型,否則會報如下錯誤

ERROR:  a column definition list is required for functions returning "record"

 

定義復合類型,示例如下

create type myout2 as (
road_num int,
freq bigint
);

create or replace function test(car text, time1 text, time2 text)
returns setof myout2 as $$

declare 
    array1 text[];
    array2 text[];
    len1 integer;
    len2 integer;
    x integer;
    y integer;
    road_str text;
    car_str text;
    sql text;
    i myout2;
    
begin
    -- vin 號拼接
    select regexp_split_to_array(car, ',') into array2;
    select array_length(array2, 1) into len2;
    car_str := '';
    y := 1;
    while y <= len2 loop
    car_str := car_str || quote_literal(array2[y]) || ',';
    y := y + 1;
    end loop;

    -- sql 拼接
    sql := 'select road_number, sum(frequency) from heat_map where date_key >= '''
    || time1
    || '-01'' and date_key <='''
    || time2
    || '-20'' and vin in ('
    || rtrim(car_str, ',') 
    || ')group by road_number;';
    --execute sql into out;
    for i in execute sql loop
    return next i;
    end loop;
    return;

end

$$ language plpgsql;

 

在執行時可能會報如下錯誤

ERROR:  set-valued function called in context that cannot accept a set

解決方法

select funcname(arg);
--改為
select * from funcname(arg);

 

2.  return query,無需 for 循環

CREATE OR REPLACE FUNCTION funcname ( in_id integer)
RETURNS SETOF RECORD as $$
DECLARE
    v_rec RECORD;
BEGIN
   return query  ( (select id , name  from test_result1  where id = in_id) union (select id , name  from test_result2  where id = in_id) );
   return;
END;
$$
LANGUAGE PLPGSQL;

 

3. 使用 out 輸出參數

 CREATE OR REPLACE FUNCTION funcname ( in_id integer,out o_id integer,out o_name varchar)
 RETURNS SETOF RECORD as $$
DECLARE
    v_rec RECORD;
BEGIN
   for v_rec in  ( (select id , name  from test_result1  where id = in_id) union (select id , name  from test_result2  where id = in_id) )loop
    o_id   := v_rec.id;
    o_name := v_rec.name;
    RETURN NEXT ;
   end loop;
   return;
END;
$$
LANGUAGE PLPGSQL;

 

總結 - return next && return query 

我們可以看到上面無論是單列多行還是多列多行,都用到了 return next 和 return query 方法

在 plpgsql 中,如果存儲過程返回 setof sometype,則返回值必須在 return next 或者 return query 中聲明,然后有一個不帶參數的 retrun 命令,告訴函數執行完畢;    【setof 就意味着 多行】

用法如下

RETURN NEXT expression;
RETURN QUERY query;
RETURN QUERY EXECUTE command-string [ USING expression [, ... ] ];

return next 可以用於標量和復合類型數據;

return query 命令將查詢到的一條結果追加到函數的結果集中;

二者在單一集合返回函數中自由混合,在這種情況下,結果將被級聯。【有待研究】

return query execute 是 return query 的變形,它指定 sql 將被動態執行;

return query select road_number, sum(frequency) from heat_map group by road_number; --這樣可以

sql := 'select road_number, sum(frequency) from heat_map group by road_number';
return query sql;    --這樣不行

 

 

 

參考資料:

https://blog.csdn.net/victor_ww/article/details/44415895  postgresql自定義類型並返回數組

https://blog.csdn.net/weixin_42767321/article/details/92992935  PG return next & return query

https://blog.csdn.net/luojinbai/article/details/45487373  PostgreSQL function返回多列多行

https://www.cnblogs.com/xiongsd/archive/2013/06/05/3118704.html  返回結果集多列和單列的例子  

https://www.cnblogs.com/lottu/p/7404722.html  PostgreSQL存儲過程(1)-基於SQL的存儲過程

https://blog.csdn.net/pg_hgdb/article/details/79692749  Postgresql動態SQL

https://stackoverflow.com/questions/40864464/postgresql-pgadmin-error-return-cannot-have-a-parameter-in-function-returning-s/40864898  postgresql, pgadmin error RETURN cannot have a parameter in function returning set

https://blog.csdn.net/qq_42535651/article/details/92089510  postgresql存儲過程輸出參數

https://www.cnblogs.com/winkey4986/p/6437811.html

https://www.cnblogs.com/lottu/p/7405829.html  PostgreSQL存儲過程(3)-流程控制語句


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM