“總結一下本人在項目中遇到的問題,如何在數據庫表名未知且作為一種查詢條件的情況下查詢出數據集,僅能通過FineReport+Oracle實現。
首先分析這個問題的條件和要求:
條件:只有一個ID,依靠這個ID能查詢出一個數據庫表名的集合(表名是通過各種字段拼接起來的)
要求:要遍歷這個數據庫表名集合查詢出對應的數據
FineReport即帆軟,可以制作模版,通過傳入變量執行模版中的SQL來生成報表。但是我無法將一個數據庫表名的集合傳入帆軟模版,這樣只能通過帆軟本身查出數據庫表名的集合。在有限的時間里我了解到要實現這樣的功能最直接的方法就是采用Oracle的存儲過程。通過各種百度、摸索最終實現了FineReport調用存儲過程。總結如下。”
一.存儲過程(參數,變量,游標)
1.測試表:
2.帶參數的存儲過程
2.1創建一個存儲過程:在Procedures文件夾右鍵New
2.2帶參數的存儲過程
create or replace procedure test(param1 in varchar2, item out sys_refcursor) as begin open item for select * from TT_CLASS_20160912 tt where tt.length = param1; end;
這里創建的是一個名為“test”的存儲過程,有兩個參數,param1為輸入參數,item為輸出參數,從“in”和“out”就可以看出來,“varchar2”和“sys_refcursor”為參數類型,其中“sys_refcursor”為游標,其實就是一個數據集合。
F8執行一次就會在Oracle里創建一個存儲過程,實際上是一個編譯過程。
右鍵該存儲過程,點擊“TEST”
填入參數,F8執行,點擊結果的小點點就能查看到結果集了
3.存儲過程的變量
修改存儲過程如下,添加了兩個變量“tableName”和“select_query”,存儲過程的變量和函數的變量相似,作用於存儲過程體,例子中我把表名和要執行的SQL都定義為變量,同2.2執行,能看到用存儲過程是有可能解決我的問題。
create or replace procedure test(param1 in varchar2,item out sys_refcursor) as tableName long; select_query long; begin tableName := 'TT_CLASS_20160912'; select_query := 'select * from ' || tableName || ' tt where tt.length = ' || param1 || ''; open item for select_query; end;
4.存儲過程的游標
接下來要解決的問題是,我所需要的表名不是單單一個字符串,而是一個結果集,我要做的是遍歷這個結果集進行查詢。這里要用到游標。
修改存儲過程如下,添加了一個變量“flag”和一個游標“myCusor”,這里我簡化了業務,游標的查詢結果為兩個表名組成的結果集。“flag”是為了在遍歷游標的時候方便判斷是否為第一條數據。
從“declare”開始到“begin”為游標的定義,一般為一個查詢結果,這里的SQL也是可以用到參數的。
“open myCusor ... loop”為遍歷游標。
“fetch myCusor into ...”為取值。
整個存儲過程體里的邏輯為:獲取游標結果集('TT_CLASS_20160912','TT_CLASS_20160922')->遍歷結果集取出游標里的值賦給變量“tableName”->拼接SQL並執行,結果賦給輸出參數“item”。
create or replace procedure test(param1 in varchar2, item out sys_refcursor) as flag int; tableName long; select_query long; begin declare cursor myCusor is select table_name from user_tables where table_name = 'TT_CLASS_20160912' or table_name = 'TT_CLASS_20160922'; begin open myCusor; flag := 1; loop fetch myCusor into tableName; exit when myCusor%notfound; if flag = 1 then flag := 0; select_query := 'select * from ' || tableName || ' where length = ' || param1 || ''; else select_query := '' || select_query || 'union (select * from ' || tableName || ' where length = ' || param1 || ')'; end if; end loop; close myCusor; open item for select_query; end; end;
執行結果:成功。當然這是在簡化了業務的情況下的結果,但是難點基本都說清楚了。基於這個方法能夠解決數據上的問題了,接下來就是FineReport的使用,畢竟光查出結果還不夠,還要將結果用報表顯示出來。
二.FineReport配置
FineReport官網:http://www.finereport.com
FineReport在線文檔:http://www.finereporthelp.com(http://help.finereport.com)
FineReport論壇:http://bbs.fanruan.com
帆軟對版本有一定要求,首先要知道自己服務器上部署的是什么版本,然后下載對應的設計器,本人用的是7.0
使用帆軟首先要定義數據連接,點擊服務器->定義數據連接
填上你的數據庫地址、用戶名和密碼,點擊測試連接,成功就說明設計器的數據連接配好了。
需要注意的是設計器制作的模版文件本身並不包含這些配置信息的,只會存一個連接的名字,比如這里配置的連接名為“test”,在模版文件里只會存“test”,具體信息會去WEB-INF\resource\datasource.xml這個文件里面讀取,所以具體該如何配置數據連接可以查看項目里的配置文件。
配置好數據連接后,創建數據庫查詢,如圖點擊數據庫查詢,就可以直接編寫SQL。
這里只寫一些測試用
創建完數據庫查詢后會在左側數據集下顯示你的查詢,和對應的字段,直接將字段拖入表格即可。
最后點擊預覽就可以查看報表數據了
三.FineReport調用存儲過程
現在我們有了存儲過程,FineReport也可以生成報表,要做的就是用FineReport調用存儲過程,只有簡單一句,如圖
點擊預覽,看看是否調用成功,傳一個參數“2”給它。
有結果了有木有。
最后我們將結果集拖入表格,如圖。
另存為模版文件,這樣我們就拿到了能夠調用存儲過程的FineReport模版。