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)

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

PostgreSQL函数如何返回数据集 [转]的更多相关文章

  1. postgresql 函数 参数为复合类型

    postgresql没有存储过程,但是函数功能很强大. 在近期开发的电商管理平台中,对于产品的类目管理,设计时有个属性字段,设为字符数组,但是EF不支持数组的操作,所以在添加和修改类目时,需要对属性的 ...

  2. PostgreSQL自学笔记:6 PostgreSQL函数

    6 PostgreSQL函数 6.2 数学函数 abs(x) 绝对值 pi() 圆周率π select abs(-3),pi(); cookie: MySQL中的pi()默认值3.141593, Po ...

  3. PostgreSQL函数(存储过程)----笔记

    PostgreSQL 函数也称为 PostgreSQL 存储过程. PostgreSQL 函数或存储过程是存储在数据库服务器上并可以使用SQL界面调用的一组SQL和过程语句(声明,分配,循环,控制流程 ...

  4. 用Python写了一个postgresql函数,感觉很爽

    用Python写了一个postgresql函数,感觉很爽 CREATE LANGUAGE plpythonu; postgresql函数 CREATE OR REPLACE FUNCTION myfu ...

  5. Oracle创建表语句(Create table)语法详解及示例、、 C# 调用Oracle 存储过程返回数据集 实例

    Oracle创建表语句(Create table)语法详解及示例 2010-06-28 13:59:13|  分类: Oracle PL/SQL|字号 订阅 创建表(Create table)语法详解 ...

  6. Entity Framework 6 Recipes 2nd Edition(11-6)译 -> 从一个”模型定义”函数里返回一个复杂类型

    11-6.从一个”模型定义”函数里返回一个复杂类型 问题 想要从一个”模型定义”函数返回一个复杂类型 解决方案 假设我们有一个病人(patient)和他们访客(visit)的模型,如 Figure 1 ...

  7. 测试函数用Return 返回值和用函数名返回值的区别

    '*************************************************************************'**模 块 名:工程1 - Form1'**说   ...

  8. Shell入门教程:Shell函数的返回值

    shell函数返回值一般有3种方式: 1.return语句(默认的返回值) shell函数的返回值可以和其他语言的返回值一样,通过return语句返回. 比如: #!/bin/bash functio ...

  9. 多层数据库应用基于Delphi DataSnap方法调用的实现(一)返回数据集

    从Delphi 2009开始,DataSnap技术发生了很大的变化,并在Delphi 2010和Delphi XE的后续版本中得到了持续的改进.Delphi 2009之前的DataSnap,虽然也实现 ...

随机推荐

  1. Bone Collector(复习01背包)

    传送门 题目大意:01背包裸题. 复习01背包: 题目 有N件物品和一个容量为V的背包.第i件物品的费用是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总 ...

  2. kitti 数据集解析

    1.KITTI数据集采集平台: KITTI数据采集平台包括2个灰度摄像机,2个彩色摄像机,一个Velodyne 3D激光雷达,4个光学镜头,以及1个GPS导航系统.坐标系转换原理参见click.KIT ...

  3. Win32编程点滴5 - 响应ActiveX控件的事件

    在最近的一篇文章中说到了,如何创建ActiveX,这次我们来响应事件.这次,我们将创建一个类:CGeneralEventSink,它能够响应任何Dispatch事件(事件的接口继承与IDispatch ...

  4. bzoj4259

    fft 搞一个生成函数 对于每位A(j)=Σi=1->m (a[i]-b[i+j])^2*a[i]*b[i+j] 如果A(j)=0说明这位匹配 如果这位是*那么a[i]=0否则等于字母-'a'+ ...

  5. 性能测试之Jmeter学习(一)

    一.Jmeter的安装: 1.安装配置要求: Java版本: Jmeter要求完全兼容的Java6或更高版本(建议安装java 8或以上版本): 操作系统:是一个100%的Java程序,它在任何支持完 ...

  6. JVM 内存区域

    JVM 将内存区域划分为: Method Area(Non-Heap)(方法区) ,Heap(堆) , Program Counter Register(程序计数器) , VM Stack(虚拟机栈, ...

  7. 【eclipse插件开发实战】Eclipse插件开发4——插件JDE、PDE开发方式及plugin.xml配置文件结构

    Eclipse插件开发4--插件JDE.PDE开发方式及plugin.xml配置文件结构 开发方式分为:java开发环境JDE开发插件的方式和插件开发环境PDE开发插件方式. 插件通过添加到预定义的扩 ...

  8. linux tar命令及解压总结

    把常用的tar解压命令总结下,当作备忘: tar -c: 建立压缩档案 -x:解压 -t:查看内容 -r:向压缩归档文件末尾追加文件 -u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其 ...

  9. Linux命令之清空当前文件

    vi进入文件 英文状态下按下  / 输入  %d 执行 清空当前文件 over!O(∩_∩)O哈哈~

  10. IntelliJ IDEA的自动提示貌似是区分大小写的,首字母小写的话,怎么都提示不出来。

    IntelliJ IDEA的自动提示貌似是区分大小写的,首字母小写的话,怎么都提示不出来. File>Settings>editor >general >code comple ...