zoukankan      html  css  js  c++  java
  • 【Oracle-PLsql】使用存储过程,利用table集合类型开发复杂业务报表

    在一般的项目中,都需要开发一些报表,少则几个字段,多则几十个字段,需要关联的表可能多达十几、几十张表,如果想要使用一个SQL语句将这几十张表关联起来

    查询所需要的字段,当你听到这里的时候,你的脑子可能已经晕掉了,这得多麻烦啊,不光多麻烦,你甚至可能还写不出来,即使你写出来了,也肯定是bug一堆。等你过

    接个月再来看看这段SQL,估计已经看不明白了。等到后人来维护你这段SQL的时候,他估计会咬牙切齿,恨不得要把这段代码的作者撕个粉碎。

    那么接下来,就给大家介绍一个Oracle的功能,使用table集合类型返回结果集,顾名思义你就可以把它看成是一个表,本来结果集也可以看成是一张表嘛。话不多说,直接来看代码。

    1.首先定义一个type,包括返回结果集所需要显示的字段。

    [sql] view plain copy
     
    1. CREATE OR REPLACE TYPE query_rpt_test force is object  
    2. (  
    3.       full_name varchar2(200),  
    4.       birth_date date,  
    5.       gender  varchar2(200)  
    6. )  


    2.接着定义table类型

    [sql] view plain copy
     
    1. CREATE OR REPLACE TYPE t_query_rpt_test is table of query_rpt_test  


    3.然后定义package

    [sql] view plain copy
     
    1. create or replace package PKG_REPORT_QUERY_TEST is  
    2.   
    3.   
    4.   --定义取数的function,传入参数分别是开始日期和截止日期  
    5.   function f_get_query_report(i_begin_date date, i_end_date date)  
    6.     --返回类型为t_query_rpt_test  
    7.     return t_query_rpt_test;  
    8.   
    9. end PKG_REPORT_QUERY_TEST;  


    4.定义package body

    [sql] view plain copy
     
    1. create or replace package body PKG_REPORT_QUERY_TEST is  
    2.   
    3.   --定义取数的function,传入参数分别是开始日期和截止日期  
    4.   function f_get_query_report(i_begin_date date, i_end_date date)  
    5.     return t_query_rpt_test as  
    6.     --返回类型为t_query_rpt_test  
    7.     m_table t_query_rpt_test;  
    8.     
    9.     --结果集行数初始值  
    10.     m_row_num number := 0;  
    11.     
    12.     --一些变量的定义  
    13.     n_list_id   number;  
    14.     v_full_name varchar2(200);  
    15.     v_birthday  date;  
    16.     v_gender    varchar2(20);  
    17.     
    18.     --游标的定义  
    19.     --这边的业务逻辑要看的该商品的购买者的姓名,生日和性别  
    20.     --此处举例比较简单,只有t_product和t_customer两张表的关联关系,完全可以两者表关联起来放在同一个cursor中,  
    21.     --这边先查询出在该区间段内的所有商品信息的主键List_id  
    22.     cursor c_product is  
    23.       select p.list_id  
    24.         from t_product p  
    25.        where p.buy_date >= i_begin_date  
    26.          and p.buy_date <= i_end_date;  
    27.     
    28.   begin  
    29.     --结果集初始化  
    30.     m_table := t_query_rpt_test();  
    31.     
    32.     --打开游标  
    33.     open c_product;  
    34.     loop  
    35.       --循环遍历游标内的每一个数据  
    36.       fetch c_product  
    37.         into n_list_id;  
    38.       exit when c_product%notfound;  
    39.           
    40.         --以下就是每个字段的取数逻辑了,除此之外,整个package的function格式都是固定的。  
    41.       --根据遍历的数据n_list_id在t_customer中查询客户信息  
    42.       select c.full_name, c.birthday, c.gender  
    43.         into v_full_name, v_birthday, v_gender  
    44.         from t_customer c  
    45.        where c.product_id = n_list_id;  
    46.       
    47.       --扩充结果集  
    48.       m_table.extend;  
    49.       --结果集行数自增1  
    50.       m_row_num := m_row_num + 1;  
    51.       --设置结果集中每个字段的值  
    52.       m_table(m_row_num) := query_rpt_test(v_full_name,  
    53.                                            v_birthday,  
    54.                                            v_gender);  
    55.     end loop;  
    56.     --循环结束,关闭游标  
    57.     close c_policy;  
    58.     --返回结果集  
    59.     return m_table;  
    60.   end f_get_query_report;  
    61.   
    62. end PKG_REPORT_QUERY_TEST;  



    
    

    好了,整个代码都编写完成了,那么我们如何来使用呢,直接编写如下语句就能返回一个结果集了。

    [sql] view plain copy
     
    1. select * from table(PKG_REPORT_QUERY_TEST.f_get_query_report(to_date('2013-01-01','yyyy-MM-dd'),to_date('2013-01-01','yyyy-MM-dd')));  

    这样的话在Java中使用也非常方便,就不用再在java代码中写一大堆SQL了。

    OK,总结一下,整个开发流程就是:

    1.定义cursor。cursor的作用只需要查询最精简最有用的信息,至于其他,通通放到取数逻辑中去。

    2.打开cursor,根据cursor中的值进行相应的取数逻辑。

    3.结果集的扩充,自增1,然后设置结果集的值。

    4.最后当然要有返回值:结果集。

    很明显,优点就是:简单方便,便于维护,以后只需要在type类型中增加相应的字段,在package中增加相应的取数逻辑,最后设上值即可。

    转自:http://blog.csdn.net/andn_pan/article/details/16946365

  • 相关阅读:
    解决magento后台无法登陆/登陆没有反应的方法
    修正magento快速搜索返回结果不准确
    怎么在手机浏览器上访问电脑本地的文件,局域网内,自建WiFi也可以
    php中cookie+mysql实现的购物车代码
    深入分析Php处理浮点数的问题
    Ecshop安装过程中的的问题:cls_image::gd_version()和不支持JPEG
    推荐mysql优化的21条经验
    Magento产品批量导入方法?
    Magento控制器
    grub uuid设置
  • 原文地址:https://www.cnblogs.com/beijingstruggle/p/7206917.html
Copyright © 2011-2022 走看看