FineReport调用存储过程
“总结一下本人在项目中遇到的问题,如何在数据库表名未知且作为一种查询条件的情况下查询出数据集,仅能通过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模版。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术