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)的更多相关文章

  1. oracle函数返回结果集

    一.用自定义类型实现 1.创建表对象类型. 在Oracle中想要返回表对象,必须自定义一个表类型,如下所示: create or replace type type_table is table of ...

  2. oracle调用存储过程和函数返回结果集

    在程序开发中,常用到返回结果集的存储过程,这个在mysql和sql server 里比较好处理,直接返回查询结果就可以了,但在oracle里面 要 out 出去,就多了一个步骤,对于不熟悉的兄弟们还得 ...

  3. oracle自定义函数返回结果集

    首先要弄两个type,不知道什么鬼: 1. create or replace type obj_table as object ( id ), name ), ) ) 2. create or re ...

  4. oracle pipelined返回值函数 针对数据汇总统计 返回结果集方法

    近期需要一个汇总统计,由于数据太多,数据量太大所以在java程序中实现比较困难.若用后台程序统计,数据不能保证实时,同时实现周期比较长.顾使用函数返回结果集的方式,在不增加临时表的情况下实时获取数据. ...

  5. Oracle中函数如何返回结果集

    在Oracle中,用函数返回结果集有时候要用到,下面是demo: 1 2 3 4 5 6 7 create or replace type t_test as object ( id integer, ...

  6. PostgreSQL函数如何返回数据集 [转]

    PostgreSQL函数如何返回数据集 以下主要介绍PostgreSQL函数/存储过程返回数据集,或者也叫结果集的示例. 背景: PostgreSQL里面没有存储过程,只有函数,其他数据库里的这两个对 ...

  7. Oracle中函数/过程返回结果集的几种方式

    原文 Oracle中函数/过程返回结果集的几种方式 Oracle中函数/过程返回结果集的几种方式:    以函数return为例,存储过程只需改为out参数即可,在oracle 10g测试通过.    ...

  8. Mybatis下配置调用Oracle自定义函数返回的游标结果集

    在ibatis和Mybatis对存储过程和函数函数的调用的配置Xml是不一样的,以下是针对Mybatis 3.2的环境进行操作的. 第一步配置Mapper的xml内容 <mapper names ...

  9. KingbaseES函数如何返回结果集

    函数返回值一般是某一类型值,如int,varchar,date等,返回结果集时就需要用到setof语法. 创建数据 create table class(id number primary key, ...

随机推荐

  1. AEAI DP开发平台精要

    1 背景概述 相信很多了解数通畅联软件的人对AEAI DP应用开发平台并不陌生,笔者在入职第一天就开始接触AEAI DP,使用AEAI DP开发过AEAI WM.AEAI CRM以及中国XXXX管理系 ...

  2. Vector和Stack(已过时,不建议使用)

    以下内容基于jdk1.7.0_79源码: 什么是Vector和Stack Vector:线程安全的动态数组 Stack:继承Vector,基于动态数组实现的一个线程安全的栈: Vector和Stack ...

  3. 【密码】Oracle用户密码系列

    [密码]Oracle用户密码系列 1.1  BLOG文档结构图 1.2  前言部分 1.2.1  导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识, ...

  4. 使用axis调用WebService服务端

    由于项目中要调用其他公司的接口,研究了下axis调用webService这种方式,现将代码贴出,以备以后查阅: package com.xbq; import javax.xml.namespace. ...

  5. InnoDB源码分析--缓冲池(二)

    转载请附原文链接:http://www.cnblogs.com/wingsless/p/5578727.html 上一篇中我简单的分析了一下InnoDB缓冲池LRU算法的相关源码,其实说不上是分析,应 ...

  6. POST和GET区别

    1. get是从服务器上获取数据,post是向服务器传送数据.2. get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到.post是通过H ...

  7. nginx日志切割脚本

    #!/bin/bash ip=`ifconfig eth0 | grep "inet addr" | cut -f 2 -d ":" | cut -f 1 -d ...

  8. 定时器的应用---查询方式---让8个LED灯,左右各4个来回亮

    定时器的应用,查询方式.让8个LED灯,左右各4个来回亮 代码: /********************** 查询方式是主程序不断的查询是否中断,而不需要准备子程序 *************** ...

  9. [引] Security tips for web developers

    Source :Security tips for web developers

  10. spring mvc 详细配置(转)

    转自: http://www.cnblogs.com/superjt/p/3309255.html 现在主流的Web MVC框架除了Struts这个主力 外,其次就是Spring MVC了,因此这也是 ...