postgresql 函数返回结果集(zz)
pgsql function 系列之一:返回结果集
--------------------------------------------------------------------------------
我们在编写postgresql数据库的函数(或称为存储过程)时,时常会遇到需要返回一个结果集的情况,如何返回一个结果集,返回一个结果集有多少种方式,以及如何选择一个合适的方式返回结果集,这是一个需要仔细考虑的问题。本文仅简单的罗列出各种返回结果集的方式并试图分析他们的特点,而采用何种方式则留给大家自己去判断。
阅读本文需要一定的postgresql数据库端编程知识,如果你缺乏这方面的知识,请先翻阅postgresql文档。
----------------------------------------------------分割线-------------------------------------------------------
第一种选择:声明setof 某表/某视图 返回类型
这是postgresql官方推荐的返回结果集的形式,当你查阅postgresql官方文档的时候,你会看到的就是这种形式。如果采用这种形式,你的function代码看起来会像这样:CREATE OR REPLACE FUNCTION function1 () RETURNS setof table1 AS
$body$
DECLARE
result record;
BEGIN
for result in select * from table1 loop
return next result;
end loop;
return;
END;
$body$
LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;
这是使用pl/pgsql语言的风格,你甚至可以使用sql语言让代码看起来更简单:
CREATE OR REPLACE FUNCTION function1 () RETURNS SETOF table1 AS
$body$
SELECT * from table1;
$body$
LANGUAGE 'sql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;
以下是分析:
首先我们说优点,第一、这是官方推荐的;第二、当使用pl/pgsql语言的时候,我们可以在循环中加上判断语句,仅返回我们需要的行;第三、在jdbc调用中,我们可以像查询普通的表一样使用这个function,例如:"select * from function1()"。
其次我们说缺点,第一、当使用pl/pgsql语言的时候,即使我们需要返回所有行,仍然要进行循环导致不必要的开销。当然你可以使用sql语言避免这个问题,但显然sql语言的控制能力太弱以至于我们无法使用它实现哪怕稍微复杂一点的逻辑。第二、返回的字段必须是在function定义时就确定了的,这意味着我们无法动态的返回我们想要返回的字段。
------------------------------------------------继续分割线-------------------------------------------------
第二种选择:声明setof record返回类型
总的说起来这种方式和上一种没什么不同,它唯一的用处在于“一定程度上”解决了动态返回结果集字段的问题。之所以说“一定程度”是因为使用setof record返回类型将会导致极度恶心的jdbc端编码——你不得不在sql语句后面显式的说明所选字段的名称和类型,并且你会发现你无法使用jdbc call的方式调用function(关于jdbc call的部分在另外的篇幅描述)。具体的来说,如果你返回一个结果集字段按照:a bigint,b varchar,c timestamp排列,则你的jdbc端编码看起来会像这样:
select * from function1() as (a bigint,b varchar,c timestamp);
问题在于,如果你不知道function将要返回的字段类型是什么,则你根本无法在jdbc端调用该function!!!
----------------------------------------------还是分割线-------------------------------------------------
第三种选择:声明refcursor返回类型
事情到这里将揭过新的一页,这里我们放弃使用setof ××× ,而使用一个全新的返回类型——refcursor(游标)。关于什么是游标本文不再累述,请自己翻阅相关文档,这里仅描述如何使用。
首先,要使用游标,你的function编码看起来会像这样:
CREATE OR REPLACE FUNCTION function1 () RETURNS refcursor AS
$body$
DECLARE
result refcursor;
BEGIN
open result for select * from table1,table2; --你可以任意选择你想要返回的表和字段
return result;
END;
$body$
LANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;
你的jdbc端编码推荐使用call方式,看起来会像这样:
Connection conn = ConnectionPool.getConn();
CallableStatement proc = conn.prepareCall("{ ? = call function1() }");
proc.execute();
ResultSet rs = (ResultSet) proc.getObject(1);
如此我们就获得了一个结果集,并且该结果集所包含的字段可以是任意你想要的字段,并且jdbc端编码也很简洁。
然而这种方式的缺点依然很明显:我们不能对要返回的结果集做进一步的筛选(参考第一种选择的优点二)。
----------------------------------------------最后分割线------------------------------------------------
总的来说,上述三种方法各有特点,我们在实际应用中应该秉着“合适的就是最好的”的原则来看待问题。
postgresql 函数返回结果集(zz)的更多相关文章
- oracle函数返回结果集
一.用自定义类型实现 1.创建表对象类型. 在Oracle中想要返回表对象,必须自定义一个表类型,如下所示: create or replace type type_table is table of ...
- oracle调用存储过程和函数返回结果集
在程序开发中,常用到返回结果集的存储过程,这个在mysql和sql server 里比较好处理,直接返回查询结果就可以了,但在oracle里面 要 out 出去,就多了一个步骤,对于不熟悉的兄弟们还得 ...
- oracle自定义函数返回结果集
首先要弄两个type,不知道什么鬼: 1. create or replace type obj_table as object ( id ), name ), ) ) 2. create or re ...
- oracle pipelined返回值函数 针对数据汇总统计 返回结果集方法
近期需要一个汇总统计,由于数据太多,数据量太大所以在java程序中实现比较困难.若用后台程序统计,数据不能保证实时,同时实现周期比较长.顾使用函数返回结果集的方式,在不增加临时表的情况下实时获取数据. ...
- Oracle中函数如何返回结果集
在Oracle中,用函数返回结果集有时候要用到,下面是demo: 1 2 3 4 5 6 7 create or replace type t_test as object ( id integer, ...
- PostgreSQL函数如何返回数据集 [转]
PostgreSQL函数如何返回数据集 以下主要介绍PostgreSQL函数/存储过程返回数据集,或者也叫结果集的示例. 背景: PostgreSQL里面没有存储过程,只有函数,其他数据库里的这两个对 ...
- Oracle中函数/过程返回结果集的几种方式
原文 Oracle中函数/过程返回结果集的几种方式 Oracle中函数/过程返回结果集的几种方式: 以函数return为例,存储过程只需改为out参数即可,在oracle 10g测试通过. ...
- Mybatis下配置调用Oracle自定义函数返回的游标结果集
在ibatis和Mybatis对存储过程和函数函数的调用的配置Xml是不一样的,以下是针对Mybatis 3.2的环境进行操作的. 第一步配置Mapper的xml内容 <mapper names ...
- KingbaseES函数如何返回结果集
函数返回值一般是某一类型值,如int,varchar,date等,返回结果集时就需要用到setof语法. 创建数据 create table class(id number primary key, ...
随机推荐
- apache 日志轮询 linux cronolog
Linux下运行的Web服务器Apache,默认日志文件是不分割的,一个整文件既不易于管理,也不易于分析统计.安装cronolog后,可以将日志文件按时间分割,易于管理和分析. cronolog安装配 ...
- Spark大数据的学习历程
Spark主要的编程语言是Scala,选择Scala是因为它的简洁性(Scala可以很方便在交互式下使用)和性能(JVM上的静态强类型语言).Spark支持Java编程,但对于使用Java就没有了Sp ...
- x01.BitmapHelper:图像处理
“所有致我于死地的,也激发我胆魄”,姚贝娜的<心火>,是我近年来听过最好的歌,特此推荐一下. 图像处理,大概分三步:1.LockBits():2.进行处理:3.UnlockBits():这 ...
- Android界面隐藏软键盘的探索(兼findViewById返回null解决办法)
最近写的APP,老师说我的登陆界面虽然有ScrollView滑动,但用户体验不太好,因为软键盘会挡住输入框或登录button(小米Pad,横屏,当指定只能输入数字时没找到关闭系统自带键盘的下箭头). ...
- Linux软件安装-RPM安装
RPM是RPM Package Manager(RPM软件包管理器)的缩写,这一文件格式名称虽然打上了RedHat的标志,但是其原始设计理念是开放式的,现在包括OpenLinux. S ...
- c++11 新特性之lambda表达式
写过c#之后,觉得c#里的lambda表达式和delegate配合使用,这样的机制用起来非常爽.c++11也有了lambda表达式,形式上有细小的差异.形式如下: c#:(input paramete ...
- FineReport构建银行金融租赁考核系统
一.应用背景 我们今天以民生银行为案例来交大家如何利用报表工具搭建金融租赁考核系统.民生银行在IT建设上已经建设邮件系统.外部网站系统.视频会议系统.OA系统.财务系统.自助报销系统.核心系统.资金管 ...
- JAVA bio nio aio
[转自]http://qindongliang.iteye.com/blog/2018539 在高性能的IO体系设计中,有几个名词概念常常会使我们感到迷惑不解.具体如下: 序号 问题 1 什么是同步? ...
- [No000038]操作系统Operating Systems -CPU
管理CPU ,先要使用CPU… CPU 的工作原理 CPU上电以后发生了什么? 自动的取指 — 执行 CPU 怎么工作? CPU怎么管理? 管理CPU 的最直观方法 设好PC 初值就完事! 看看这样做 ...
- 隐写技巧——利用JPEG文件格式隐藏payload
0x00 前言 继续对图片隐写技巧的学习,这次是对JPEG文件格式的学习和理解.同PNG文件的格式对比,JPEG文件相对简单,读取其中隐藏payload的方式大同小异,两者区别在于文件格式不同,可供利 ...