天涯论坛

 找回密码
 立即注册
搜索
查看: 19|回复: 2

报表工具的动态数据源实现

[复制链接]

2996

主题

3万

回帖

9910万

积分

论坛元老

Rank: 8Rank: 8

积分
99109194
发表于 2024-10-3 08:49:38 | 显示全部楼层 |阅读模式

有时候咱们需要用参数动态指定数据源,或将都数据源连接为单数据源,或向子报表、table控件动态传入数据源名。针对此类需要,报表工具经常要借助高级语言实现或牺牲安全性以降低繁杂度,尤其是BIRT、Jasper等单源报表。

使 用免费的集算器能够弥补这一不足。集算器封装了丰富的结构化计算函数,支持动态解析表达式,支持都数据源混合计算,书写简单脚本就能实现动态数据源。集算 器还供给了简单易用的JDBC接口,报表工具可将集算器脚本文件当做数据库存储过程执行,传入参数并用JDBC得到返回结果。

集算器与报表工具的集成结构如下:

下面举例说明集算器按照参数动态切换数据源的基本过程:

数据源myDB1和oraDB分别指向区别的数据库,两库中有相同结构的表sOrder,报表需要按照参数动态连接数据源,查找并展现sOrder中金额大于1000的订单。

myDB1中sOrder部分数据如下:

oraDB中sOrder部分数据如下:

集算器代码:

=${pSource}.query("select * from sOrderwhere Amount>?",pAmount)

pSource、pAmount都是报表参数,其中pSource表率数据源名,${…}暗示将字符串或字符串变量解析为表达式,pAmount表率订单金额。

当pSource=”myDB1”时,A1的计算结果如下:

当pSource=”oraDB”时,A1的计算结果如下:

报表工具可用JDBC的方式调用集算器脚本,就像调用普通数据库中的存储过程,形如:call 脚本文件名(参数1…参数N)。集算器的返回结果会以普通数据集的形式参与报表计算。详细用法可参考下列文档:集算器集成与应用之JasperReport集成 和集算器集成与应用之BIRT集成 。

做为专业的报表数据源工具,集算器还能够实现更加多的计算,下面分别举例。

多源数据join后计算

Sales是mysql数据库中的表,存储着多名营销每日的多个订单,其中字段SellerId是营销员编号。emp是mssql数据库中的表,存储着 营销员信息,其中字段EId是营销员编号。此刻需要在报表中展现:订单编号、日期、金额、营销员名字、分部叫作要求是:订单日期在近期N天(例如30 天)订单属于某几个受关注的分部例如Markeding和Finance)。部分源数据如下:

库表sales

库表emp

集算器代码:

A1,A2:查找数据库,myDB1和myDB2分别直向mysql和mssql。

A3:将A1中的SellerId字段替换成A2中对应的记录,相关字段为EId。A3的计算结果如下(蓝色字体暗示该数据项包括下级成员):

当A2中找不到对应的记录时,函数switch默认保存A1中记录,对应的SellerId表示为空,效果类似于左连接。倘若想进行内连接,应当运用选项@i,形如:A1.switch@i(SellerId,A2:EId)

A4:对相关结果进行过滤,第1个要求是:订单日期在近期N天(对应参数days),表达式为OrderDate>=after(date(now),days*-1)。第2个要求是:订单属于某几个受关注的分部(对应参数depts),表达式是depts.array.pos(SellerId.Dept)。运算符||暗示规律关系“或”。

函数after能够算出相对时间,函数array能够按分隔符将字符串拆分为集合。函数pos能够找出成员在集合中的位置。SellerId.Dept暗示SellerId字段对应的记录的Dept字段。

Days和depts都是来自于报表的参数,倘若分别输入30、"Marketing,Finance",则A4的结果如下:

A5:从A4中取得报表需要的字段,最后计算结果如下:

结果集union

结果集ds1和ds2结构相同,分别来自mySQL和文本文件,需要将ds1和ds2纵向拼接起来再呈现为交叉表。源数据如下:

集算器代码:

A3:纵向拼接两个数据集。报表工具只需呈现基于单数据集的简单交叉表。

主子报表都数据源

针对单数据源报表,倘若同一张报表中的主表和子表运用区别的数据源,就需要显式传递数据库URL,或用JAVA类合并区别的数据源,前者安全性较低,后者代码繁杂运用集算器能够方便地处理此类问题,下面用例子来讲明。

设计一张主子报表,按薪酬范围表示每位员工的订单信息,主报表数据来自表emp(MySQL数据库),子报表数据来自表sales(MSSQL数据库)。部分源数据如下:

集算器代码:

empEsProc.dfx(该脚本文件用于主报表)

A1:按薪酬范围查找MYSQL数据库的表emp。

salesEsProc.dfx(该脚本文件用于子报表)

A1:按员工ID从MSSQL的sales表查询相应的订单。倘若eid=1,则A1的计算结果如下:

能够看到,区别的数据源可被集算器合并为单一数据源,主子报表只需调用区别的集算器文件就可实现本需要

有些报表系统会存在多种数据源,各报表运用的数据源区别且经常出现变更,管理起来难度很强运用集算器单一数据源能够降低管理难度。

类似地,单一数据源还能够处理子报表都数据源的问题,即:报表中存在多个子报表(或table控件),每一个子报表运用区别的数据源。

主子表动态相关

主表关联的子表分布在多个数据库中,需求报表呈现这些数据源动态相关的结果。此类需要能够用集算器简单实现,例如:

主 表org在数据源Master中,org里每条记录对应的子表在不同的数据源中,例如org.org_id=”ORG_S”时,这条记录对应的子表是数据 源S_odaURL的User表,org.org_id=”ORG_T”时,这条记录对应的子表是数据源T_odaURL中的User表。子表不止两个, 名字都是User,需要和主表动态相关再呈此刻报表中。规律上的关系如下:

集算器代码如下:

A1:执行SQL,从数据源Master的org表取数据。arg1是来自报表的参数,arg1=”ORG”时A1的计算结果如下:

A2:依次循环A1中的记录,每次动态相关一个子表,并将相关结果合并在B2中。集算器用自然缩进来暗示循环语句的功效范围,即B2-B7,循环体中可用A2来引用循环变量,可用#A2来引用循环计数。

B2:按照当前记录的org_id字段计算出对应子表的数据源名。第1次循环时,B2的计算结果为” S_odaURL”。

B3:按照名字显式连接到数据源。

B4:按要求查找user表中的数据。

B5:在子表B4中新增三列,数据来自主表。例如第1次循环时,B5计算结果如下:

B6:将B5的计算结果合并到B1,运算符”|”等价于函数union。循环结束后B1会存储报表需要的完整数据,如下:

B7:显式关闭数据源连接。

A8:将B1显式返回给报表工具(默认会返回最后一个单元格)

按照参数表示时间精度区别的数据

报 表需要用折线图展现近期的营销额变化。unitType是报表参数,表率时间精度,当unitType等于"hour"时,需要展现近1小时内每五分钟的 营销额,当unitType="day"时,需要展现近1天内每小时的营销额,当unitType="week"时,需要展现近1周内每日营销额。数据 源自于orders表,字段Amount是订单金额,t是订单出现时间。

集算器代码:

A1:空结果集,用来存储B2-B4产生的时间序列。

A2-B2:按照报表参数unitType生成区别的时间序列,B2可生成近1小时内的12个时间点,每一个时间点间隔5分钟,B3生成近1天内的时间点,B4生成近1周的时间点。

A5:循环A1,每次统计一个时间段内的营销额,"~"暗示A1的当前成员,"~[-1] "暗示上一个成员。当unitType="day",会生成12条记录的单字段结果集。

A6:将A5经过JDBC传给报表。之后就能够按普通统计图的办法去呈现。





上一篇:知识图谱构建利器:图数据库Neo4j的环境安排和简单运用
下一篇:地球微生物组计划介绍(EMP)
回复

使用道具 举报

2996

主题

3万

回帖

9910万

积分

论坛元老

Rank: 8Rank: 8

积分
99109194
 楼主| 发表于 2024-10-19 19:57:52 | 显示全部楼层
你的努力一定会被看见,相信自己,加油。
回复

使用道具 举报

3070

主题

3万

回帖

9915万

积分

论坛元老

Rank: 8Rank: 8

积分
99158931
发表于 2024-11-7 05:55:43 | 显示全部楼层
你的见解真是独到,让我受益匪浅。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

站点统计|Archiver|手机版|小黑屋|天涯论坛 ( 非经营性网站 )|网站地图

GMT+8, 2024-11-23 05:41 , Processed in 0.106970 second(s), 22 queries .

Powered by Discuz! X3.4

Copyright © 2001-2023, Tencent Cloud.