【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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM