在我所做过和参与的大多数项目中,都会有用户提出的复杂的一些统计报表之内的功能要求,根据统计的复杂程度、效率及JAVA程序调用的方便性方面考虑,主要总结出以下几种方案:

1、SQL语句

该方案只能实现一些相对简单些的查询统计功能,语句嵌套多、写起来特别复杂,使程序的可读性变差,下面是实现一个按照上级机关统计下级各个公安机关管辖范围内对应的各个类别社会单位数量的统计功能的SQL:

Sql代码  
  1. select rpad(gajg_dm,12,'0'),
  2. sum(decode(C01, 0, 0, C01)) as C01,
  3. sum(decode(C02, 0, 0, C02)) as C02,
  4. sum(decode(C03, 0, 0, C03)) as C03,
  5. sum(decode(C04, 0, 0, C04)) as C04,
  6. sum(decode(C05, 0, 0, C05)) as C05,
  7. sum(decode(C06, 0, 0, C06)) as C06,
  8. sum(decode(C07, 0, 0, C07)) as C07,
  9. sum(decode(C08, 0, 0, C08)) as C08,
  10. sum(decode(C09, 0, 0, C09)) as C09,
  11. sum(decode(C10, 0, 0, C10)) as C10,
  12. sum(decode(C11, 0, 0, C11)) as C11
  13. from
  14. (
  15. select substr(b.gajg_dm,0,decode(substr(b.gajg_dm,0,8),'41000030',8,'41000006',8,'41000061',8,'41000060',8,4)) gajg_dm,/*b.gajg_dm,*/ cslb_dm,
  16. sum(decode(cslb_dm, '01', 1, 0)) as C01,
  17. sum(decode(cslb_dm, '02', 1, 0)) as C02,
  18. sum(decode(cslb_dm, '03', 1, 0)) as C03,
  19. sum(decode(cslb_dm, '04', 1, 0)) as C04,
  20. sum(decode(cslb_dm, '05', 1, 0)) as C05,
  21. sum(decode(cslb_dm, '06', 1, 0)) as C06,
  22. sum(decode(cslb_dm, '07', 1, 0)) as C07,
  23. sum(decode(cslb_dm, '08', 1, 0)) as C08,
  24. sum(decode(cslb_dm, '09', 1, 0)) as C09,
  25. sum(decode(cslb_dm, '10', 1, 0)) as C10,
  26. sum(decode(cslb_dm, '11', 1, 0)) as C11
  27. from yf_cs_jbxx a, dm_gajg b where b.gajg_dm=a.gajg_dm(+) and b.gajg_dm like '41%' --and b.gajg_pcs_bz<>'N'
  28. --group by substr(b.gajg_dm,0,4), cslb_dm
  29. group by substr(b.gajg_dm,0,decode(substr(b.gajg_dm,0,8),'41000030',8,'41000006',8,'41000061',8,'41000060',8,4)),cslb_dm
  30. ) t group by rpad(gajg_dm,12,'0')--gajg_dm

在该SQL语句中,主要有三个步骤:

1)统计各个机关下各个类别的单位数量

2)对编码不规则机关进行decode和截位处理

3)对1中的统计结果进行行列转换

够复杂了吧,而且还很别扭,看着就晕。。。。更别说代码数据再发生点变化了

2、存储过程返回游标

对于该方案是被我们直接PASS掉的一种方案,主要考虑其性能太差,这里就不再啰嗦了

3、临时表(或中间表)

对于该方案主要分为两步完成统计:

1)通过存储过程或函数完成对数据的统计

2)将统计结果插入到临时表中

这样程序在执行统计时就要求先调用执行统计的存储过程,然后再查询临时表以取出存储过程产生的统计结果

呵呵,每个统计还要对应建一个临时表,看着就闲麻烦。。。

4、管道表函数

管道化表函数是我见过的最佳的实现统计的解决方案(当然是在我做的项目中,具体东西具体环境具体应用吗),这里给出两个实例和说明,供大家参考,但该方案同样有一个缺点,就是在PLSQL下调试极其不方面,但基本还能忍受

Sql代码  
  1. CREATE OR REPLACE PACKAGE pkg1 AS
  2. -- Purpose : 对表函数的应用实例
  3. TYPE ty_rec_user IS record (--定义一个record类型的TYPE
  4. id number(20),
  5. name varchar2(60)
  6. );
  7. TYPE out_rec_set is table of ty_rec_user;--定义一个嵌套表集合类型out_rec_set,作为表函数的返回类型
  8. --定义返回集合类型的管道表函数
  9. FUNCTION f1(x NUMBER) RETURN out_rec_set PIPELINED;
  10. --引用在外部自定义的object类型作为表函数的集合类型
  11. TYPE out_obj_set is table of TY_OBJ_USER;
  12. FUNCTION F_PIE_TEST(c NUMBER) RETURN out_obj_set PIPELINED;
  13. END pkg1;
  14. CREATE OR REPLACE PACKAGE BODY pkg1 AS
  15. -- Purpose : 对表函数的应用实例
  16. FUNCTION f1(x NUMBER) RETURN out_rec_set PIPELINED IS
  17. user_rec ty_rec_user;
  18. BEGIN
  19. FOR i IN 1..x LOOP
  20. --user_rec:=ty_rec_user(i,'user'||i);--ty_rec_user定义为record类型时不能这样赋值,只有定义成obj时才可以
  21. user_rec.id:=i;
  22. user_rec.name:='user'||i;
  23. --PIPE ROW(1, 'user'||1);
  24. pipe row(user_rec);
  25. END LOOP;
  26. RETURN;
  27. END;
  28. --使用在外部自定义的object类型表函数
  29. FUNCTION F_PIE_TEST(c NUMBER) RETURN out_obj_set PIPELINED is
  30. user_ty_obj TY_OBJ_USER;
  31. BEGIN
  32. FOR i in 1..c LOOP
  33. user_ty_obj:=TY_OBJ_USER(i,'name'||i);
  34. PIPE ROW(user_ty_obj);
  35. END LOOP;
  36. RETURN;
  37. END;
  38. END pkg1;
  39. --外部自定义的object类型
  40. create or replace type TY_OBJ_USER as object
  41. (
  42. -- Purpose : 测试
  43. id number(20),
  44. name varchar2(60),
  45. )

表函数的调用:

Sql代码  
  1. select * from table(pkg1.f1(4))--直接在plsql中执行
Sql代码  
  1. select *  FROM  TABLE(CAST(pkg1.f1(4) AS out_rec_set))--java端程序调用

看到这相信很多人已经开始感觉到爽了吧~~,特别是数据开发人员,不用再在数 据端实现统计后还要给应用程序开发人员讲半天如何调用了,应用程序开发人员在调用复杂的统计时一个select语句就搞定,不用考虑什么游标啊、临时表这 些乱七八糟的东西了,直接一个select就出来结果,和查询一个表一样的简单

oracle管道化表函数相关推荐

  1. oracle 管道化表函数(Pipelined Table) [转]

    http://log-cd.javaeye.com/blog/411123 关键字: oracle pipelined table 在实际的应用中,为了让PL/SQL 函数返回数据的多个行,必须通过返 ...

  2. Oracle 管道化表函数(Pipelined Table)[转载]

    在实际的应用中,为了让PL/SQL 函数返回数据的多个行,必须通过返回一个 REF CURSOR 或一个数据集合来完成.REF CURSOR 的这种情况局限于可以从查询中选择的数据,而整个集合在可以返 ...

  3. oracle 管道通信,oracle管道化表函数

    转自:http://pengfeng.javaeye.com/blog/260360 在我所做过和参与的大多数项目中,都会有用户提出的复杂的一些统计报表之内的功能要求,根据统计的复杂程度.效率及JAV ...

  4. oracle表 游标,Oracle游标表达式和表函数

    Oracle游标表达式是Oracle数据库中的重要概念,下面就为您详细介绍Oracle游标表达式和表函数方面的知识,供您参考学习之用. Oracle游标表达式(有时称为游标子队列)是 SQL 语言的一 ...

  5. oracle的dual表

    1.DUAL表的用途 Dual 是 Oracle中的一个实际存在的表,任何用户均可读取,常用在没有目标表的Select语句块中 --查看当前连接用户 Connected to Oracle Datab ...

  6. Oracle常用系统表

    1.1 基于SQL的常用系统表 1.2.1 系统对象表 sysobjects  功能说明:保存当前数据库的对象,如约束.默认值.日志.规则.存储过程等 重要字段解释: sysObjects ( Nam ...

  7. oracle 临时表存在哪里_openGauss魔改PG?它能兼容Oracle的数据库表吗?

    作者介绍 洪烨,openGauss Contributor,多年银行业系统架构设计及DBA实战经验,<DB2数据库内部解析与性能调优>作者. openGauss的前世今生 上一篇看到很多朋 ...

  8. Oracle数据库之单行函数

    oracle安装参照: Oracle数据库之安装教程 Oracel数据库总结: Oracle数据库之基本查询 Oracle数据库之单行函数 Oracle数据库之多行函数 Oracle数据库之多表查询 ...

  9. Oracle常用数据字典表

    Oracle常用数据字典表  查看当前用户的缺省表空间 SQL>select username,default_tablespace from user_users;  查看当前用户的角色 SQ ...

最新文章

  1. ignite服务中的bean注入为空
  2. redis操作大数据
  3. 超不清视频播放器-用Python将视频转成字符
  4. ssl提高组周一备考赛【2018.10.29】
  5. 【深度学习】TensorFlow之卷积神经网络
  6. Word编写论文十大技巧
  7. Pandas 文本数据方法 slice( )
  8. hive join on 条件 与 where 条件区别
  9. Java经典算法50道题
  10. 将多个markdown文件发布为一个html或pdf文件的方法梳理
  11. 【solitidy】生成随机数算法
  12. 微信小程序电商实战-购物车(上)
  13. ABBYY软件的OCR文字识别工具有什么用
  14. IDS与IPS的区别是什么?
  15. 切换阿里巴巴开源镜像站镜像——Kali镜像
  16. 笨方法学python 习题26
  17. 如何一键免费压缩PDF文件?最好的 PDF 阅读器免费下载!
  18. 拿什么拯救炒币上瘾的你
  19. 【IDEA】小技巧之书签与收藏
  20. IPhone平滑滚动效果的实现

热门文章

  1. vue-cli3.0 移动端适配
  2. ES _source字段介绍——json文档,去掉的话无法更新部分文档,最重要的是无法reindex...
  3. 用InstallShield 打包工具 打 Win32 程序 (depends.exe 用看程序都依赖了哪些dll)
  4. Qt学习一门:直接使用QT具
  5. 5008.工程师职场能力自测评估
  6. SQL Server 2005 For XML[学习]
  7. 51 nod 机器人走方格
  8. Android开发之底部导航栏标准
  9. 敏捷开发中Scrum方法
  10. 网络硬盘与传统资源共享的不同