PostgreSQL函数如何返回数据集

以下主要介绍PostgreSQL函数/存储过程返回数据集,或者也叫结果集的示例。

背景: PostgreSQL里面没有存储过程,只有函数,其他数据库里的这两个对象在PG里都叫函数。
函数由函数头,体和语言所组成,函数头主要是函数的定义,变量的定义等,函数体主要是函数的实现,函数的语言是指该函数实现的方式,目前内置的有c,plpgsql,sql和internal,可以通过pg_language来查看当前DB支持的语言,也可以通过扩展来支持python等

函数返回值一般是类型,比如return int,varchar,返回结果集时就需要setof来表示。

一、数据准备

create table department(id int primary key, name text);
create table employee(id int primary key, name text, salary int, departmentid int references department); insert into department values (1, 'Management'),(2, 'IT'),(3, 'BOSS'); insert into employee values (1, 'kenyon', 30000, 1);
insert into employee values (2, 'francs', 50000, 1);
insert into employee values (3, 'digoal', 60000, 2);
insert into employee values (4, 'narutu', 120000, 3);

二、例子
1.sql一例

create or replace function f_get_employee()
returns setof employee
as
$$
select * from employee;
$$
language 'sql';

等同的另一个效果(Query)

create or replace function f_get_employee_query()
returns setof employee
as
$$
begin
return query select * from employee;
end;
$$
language plpgsql;

查询图解如下

postgres=# select * from f_get_employee();
id | name | salary | departmentid
----+--------+--------+--------------
1 | kenyon | 30000 | 1
2 | francs | 50000 | 1
3 | digoal | 60000 | 2
4 | narutu | 120000 | 3
(4 rows)

查询出来的函数还可以像普通的表一样按条件查询 ,但如果查询的方式不一样,则结果也不一样,以下查询方式将会得到类似数组的效果

postgres=# select f_get_employee();
f_get_employee
---------------------
(1,kenyon,30000,1)
(2,francs,50000,1)
(3,digoal,60000,2)
(4,narutu,120000,3)
(4 rows)

因为返回的结果集类似一个表的数据集,PostgreSQL还支持对该函数执行结果进行条件判断并过滤

postgres=# select * from f_get_employee() where id >3;
id | name | salary | departmentid
----+--------+--------+--------------
4 | narutu | 120000 | 3
(1 row)

上面的例子相对简单,如果要返回不是表结构的数据集该怎么办呢?看下面

2.返回指定结果集

--a.用新建type来构造返回的结果集

--新建的type在有些图形化工具界面中可能看不到,
--要查找的话可以通过select * from pg_class where relkind='c'去查,c表示composite type create type dept_salary as (departmentid int, totalsalary int); create or replace function f_dept_salary()
returns setof dept_salary
as
$$
declare
rec dept_salary%rowtype;
begin
for rec in select departmentid, sum(salary) as totalsalary from f_get_employee() group by departmentid loop
return next rec;
end loop;
return;
end;
$$
language 'plpgsql'; --b.用Out传出的方式 create or replace function f_dept_salary_out(out o_dept text,out o_salary text)
returns setof record as
$$
declare
v_rec record;
begin
for v_rec in select departmentid as dept_id, sum(salary) as total_salary from f_get_employee() group by departmentid loop
o_dept:=v_rec.dept_id;
o_salary:=v_rec.total_salary;
return next;
end loop;
end;
$$
language plpgsql;
--执行结果:

postgres=# select * from f_dept_salary();
departmentid | totalsalary
--------------+-------------
1 | 80000
3 | 120000
2 | 60000
(3 rows) postgres=# select * from f_dept_salary_out();
o_dept | o_salary
--------+----------
1 | 80000
3 | 120000
2 | 60000
(3 rows) --c.根据执行函数变量不同返回不同数据集 create or replace function f_get_rows(text) returns setof record as
$$
declare
rec record;
begin
for rec in EXECUTE 'select * from ' || $1 loop
return next rec;
end loop;
return;
end
$$
language 'plpgsql'; --执行结果: postgres=# select * from f_get_rows('department') as dept(deptid int, deptname text);
deptid | deptname
--------+------------
1 | Management
2 | IT
3 | BOSS
(3 rows) postgres=# select * from f_get_rows('employee') as employee(employee_id int, employee_name text,employee_salary int,dept_id int);
employee_id | employee_name | employee_salary | dept_id
-------------+---------------+-----------------+---------
1 | kenyon | 30000 | 1
2 | francs | 50000 | 1
3 | digoal | 60000 | 2
4 | narutu | 120000 | 3
(4 rows)

这样同一个函数就可以返回不同的结果集了,很灵活。

最新文章

  1. Log4j写日志文件使用详解
  2. JAVA中的输入方法
  3. Chrome插件开发
  4. mongodb学习03 操作详解
  5. mtk的安卓手机刷机时出现的错误信息
  6. Shell概述
  7. sqlite多表关联update
  8. docker 容器数据管理
  9. Ceph相关博客、网站(256篇OpenStack博客)
  10. 功能代码(1)---通过Jquery来处理复选框
  11. keras图像风格迁移
  12. jquery.ocupload上传文件到指定目录
  13. 洛谷 P5020 【货币系统】
  14. win 右键菜单栏出现sublime打开方式
  15. CSS3-Hover 效果 展示
  16. 【python】Python 中的 classmethod 和 staticmethod
  17. js便签笔记(12)——浏览TOM大叔博客的学习笔记 part2
  18. 使用 IntraWeb (19) - 基本控件之 TIWTreeView
  19. 程序员必备!Sonar代码质量管理工具
  20. 安装mysql 和 apache

热门文章

  1. Git 常用命令学习
  2. POJ2823(优先队列)
  3. HDU-2553
  4. 1.17 shell action
  5. TCPflow:在Linux中分析和调试网络流量的利器(转)
  6. UVaLive 2965 Jurassic Remains (状态压缩)
  7. myeclipse同时部署两个项目-permgen space
  8. 洛谷 - P1414 - 又是毕业季II - 因数
  9. 在mpvue框架中使用Vant WeappUI组件库的注意事项
  10. PJzhang:尽快发现并下架那些侵犯公司权利的假冒APP