热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PostgreSQL函数如何返回数据集

以下主要介绍PostgreSQL函数/存储过程返回数据集,或者也叫结果集的示例。背景:PostgreSQL里面没有存储过程,只有函数,其他数据库里的这两个对象在PG里都叫函数。函数由函数头,体和语言所组成,函数头主要是函数的定义,变量的定义等,函数体主要是函数
以下主要介绍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)
这样同一个函数就可以返回不同的结果集了,很灵活。
推荐阅读
  • 本文详细介绍 Go+ 编程语言中的上下文处理机制,涵盖其基本概念、关键方法及应用场景。Go+ 是一门结合了 Go 的高效工程开发特性和 Python 数据科学功能的编程语言。 ... [详细]
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • 技术分享:从动态网站提取站点密钥的解决方案
    本文探讨了如何从动态网站中提取站点密钥,特别是针对验证码(reCAPTCHA)的处理方法。通过结合Selenium和requests库,提供了详细的代码示例和优化建议。 ... [详细]
  • 1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ... [详细]
  • 如何在PHPcms网站中添加广告
    本文详细介绍了在PHPcms网站后台添加广告的方法,涵盖多种常见的广告形式,如百度广告和Google广告,并提供了相关设置的步骤。同时,文章还探讨了优化网站流量的SEO策略。 ... [详细]
  • 在哈佛大学商学院举行的Cyberposium大会上,专家们深入探讨了开源软件的崛起及其对企业市场的影响。会议指出,开源软件不仅为企业提供了新的增长机会,还促进了软件质量的提升和创新。 ... [详细]
  • 深入理解C++中的KMP算法:高效字符串匹配的利器
    本文详细介绍C++中实现KMP算法的方法,探讨其在字符串匹配问题上的优势。通过对比暴力匹配(BF)算法,展示KMP算法如何利用前缀表优化匹配过程,显著提升效率。 ... [详细]
  • Python自动化处理:从Word文档提取内容并生成带水印的PDF
    本文介绍如何利用Python实现从特定网站下载Word文档,去除水印并添加自定义水印,最终将文档转换为PDF格式。该方法适用于批量处理和自动化需求。 ... [详细]
  • 在当前众多持久层框架中,MyBatis(前身为iBatis)凭借其轻量级、易用性和对SQL的直接支持,成为许多开发者的首选。本文将详细探讨MyBatis的核心概念、设计理念及其优势。 ... [详细]
  • 如何在PostgreSQL中查看数据表
    本文将指导您使用pgAdmin工具连接到PostgreSQL数据库,并展示如何浏览和查找其中的数据表。通过简单的步骤,您可以轻松访问所需的表结构和数据。 ... [详细]
  • 离线环境下的Python及其第三方库安装指南
    在项目开发中,有时会遇到电脑只能连接内网或完全无法联网的情况。本文将详细介绍如何在这种环境下安装Python及其所需的第三方库,确保开发工作的顺利进行。 ... [详细]
  • [论文笔记] Crowdsourcing Translation: Professional Quality from Non-Professionals (ACL, 2011)
    Time:4hoursTimespan:Apr15–May3,2012OmarZaidan,ChrisCallison-Burch:CrowdsourcingTra ... [详细]
  • 深入解析JVM垃圾收集器
    本文基于《深入理解Java虚拟机:JVM高级特性与最佳实践》第二版,详细探讨了JVM中不同类型的垃圾收集器及其工作原理。通过介绍各种垃圾收集器的特性和应用场景,帮助读者更好地理解和优化JVM内存管理。 ... [详细]
  • 资源推荐 | TensorFlow官方中文教程助力英语非母语者学习
    来源:机器之心。本文详细介绍了TensorFlow官方提供的中文版教程和指南,帮助开发者更好地理解和应用这一强大的开源机器学习平台。 ... [详细]
  • 本文介绍了如何在Python中使用join()方法将列表中的元素连接成一个字符串。join()方法允许用户指定分隔符,从而灵活地生成所需格式的字符串。此外,我们还将探讨一些实际应用中的注意事项和技巧。 ... [详细]
author-avatar
寤丨惘_191
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有