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函数如何返回数据集的更多相关文章
- PostgreSQL函数如何返回数据集 [转]
PostgreSQL函数如何返回数据集 以下主要介绍PostgreSQL函数/存储过程返回数据集,或者也叫结果集的示例. 背景: PostgreSQL里面没有存储过程,只有函数,其他数据库里的这两个对 ...
- postgresql 函数 参数为复合类型
postgresql没有存储过程,但是函数功能很强大. 在近期开发的电商管理平台中,对于产品的类目管理,设计时有个属性字段,设为字符数组,但是EF不支持数组的操作,所以在添加和修改类目时,需要对属性的 ...
- PostgreSQL自学笔记:6 PostgreSQL函数
6 PostgreSQL函数 6.2 数学函数 abs(x) 绝对值 pi() 圆周率π select abs(-3),pi(); cookie: MySQL中的pi()默认值3.141593, Po ...
- PostgreSQL函数(存储过程)----笔记
PostgreSQL 函数也称为 PostgreSQL 存储过程. PostgreSQL 函数或存储过程是存储在数据库服务器上并可以使用SQL界面调用的一组SQL和过程语句(声明,分配,循环,控制流程 ...
- 用Python写了一个postgresql函数,感觉很爽
用Python写了一个postgresql函数,感觉很爽 CREATE LANGUAGE plpythonu; postgresql函数 CREATE OR REPLACE FUNCTION myfu ...
- Oracle创建表语句(Create table)语法详解及示例、、 C# 调用Oracle 存储过程返回数据集 实例
Oracle创建表语句(Create table)语法详解及示例 2010-06-28 13:59:13| 分类: Oracle PL/SQL|字号 订阅 创建表(Create table)语法详解 ...
- Entity Framework 6 Recipes 2nd Edition(11-6)译 -> 从一个”模型定义”函数里返回一个复杂类型
11-6.从一个”模型定义”函数里返回一个复杂类型 问题 想要从一个”模型定义”函数返回一个复杂类型 解决方案 假设我们有一个病人(patient)和他们访客(visit)的模型,如 Figure 1 ...
- 测试函数用Return 返回值和用函数名返回值的区别
'*************************************************************************'**模 块 名:工程1 - Form1'**说 ...
- Shell入门教程:Shell函数的返回值
shell函数返回值一般有3种方式: 1.return语句(默认的返回值) shell函数的返回值可以和其他语言的返回值一样,通过return语句返回. 比如: #!/bin/bash functio ...
- 多层数据库应用基于Delphi DataSnap方法调用的实现(一)返回数据集
从Delphi 2009开始,DataSnap技术发生了很大的变化,并在Delphi 2010和Delphi XE的后续版本中得到了持续的改进.Delphi 2009之前的DataSnap,虽然也实现 ...
随机推荐
- 解析【.mdb】文件
有一些项目用的是微软的access软件,这里面存放数据用的是mdb结尾的文件 有的时候,客户想开发一个新的系统,但是数据需要从这些文件中获取,因此得解析这些文件,来提取数据 一.解析时用到的依赖 1. ...
- adb安装电视apk
adb 是什么? 百度说明:adb工具即Android Debug Bridge(安卓调试桥) tools.它就是一个命令行窗口,用于通过电脑端与模拟器或者真实设备交互.在某些特殊的情况下进入不了系统 ...
- RabbitMQ、RocketMQ、Kafka延迟队列实现
延迟队列在实际项目中有非常多的应用场景,最常见的比如订单未支付,超时取消订单,在创建订单的时候发送一条延迟消息,达到延迟时间之后消费者收到消息,如果订单没有支付的话,那么就取消订单. 那么,今天我们需 ...
- JavaScript:七大基础数据类型:大整数bigint
因为数值number有表示范围,所以当我们需要精确表示更大的数字时,我们需要用到大整数bigint: 事实上,大整数可以精确表示任意长度的整数: 我们可以通过在整数的末尾添加字母n,来声明它是一个大整 ...
- 3、数组、集合、Lambda、Stream与Optional类
一.数组: 数组保存在JVM堆内存中 1.数组的创建: (1).一维数组创建方式一: //一维数组方式一 Integer[] array01 = {1,2,3}; System.out.println ...
- [编程基础] Python格式化字符串常量f-string总结
Python格式化字符串常量f-string总结 本文主要总结在Python中如何使用格式化字符串常量f-string(Formatted string literals).在 Python 程序中, ...
- Pytorch基础-tensor数据结构
torch.Tensor Tensor 数据类型 Tensor 的属性 view 和 reshape 的区别 Tensor 与 ndarray 创建 Tensor 传入维度的方法 参考资料 torch ...
- 使用 Link Cut Tree 维护最小生成树
简介 本文将简单介绍如何使用 Link Cut Tree 维护动态图最小生成树. 思路 最小生成树的性质:一个基环树的最小生成树,为将环上边权最大的边删除后所组成的树. Proof:如果删除环上的其他 ...
- 序列化框架-Kyro简述
网上有很多资料说 Kryo 只能在 Java 上使用,这点是不对的,事实上除 Java 外,Scala 和 Kotlin 这些基于 JVM 的语言同样可以使用 Kryo 实现序列化. 1.使用方法 ( ...
- 超详细版本vue+capacitor(自定义capacitor插件)编写移动端应用
我的环境 Node v16.13.0 npm v8.1.0 mac的话需要安装Xcode windows的话需要Java 8 JDK和Android Studio软件 本文以安卓开发为例 找一个自己喜 ...