润乾报表实践:可在数据库间移植的报表

需求描述

行业软件公司的解决方案会面对不同的用户,开发的报表也要适应不同的用户,而不同用户的数据库可能不同,这就需要报表能够在不同数据库上移植
比如下面的报表,统计自起始日起,各个员工一个月内的订单情况

imagepng
数据结构是这样的:

imagepng

我们需要让这类报表在 MYSQL 和 ORACLE 上都能正常运行

问题分析

这个报表本身样式很容易制作,麻烦在于数据源
报表大都是通过 SQL 来从数据库中取数计算的,如果 SQL 是通用的,那不管对接什么库都没问题,但问题就在于 SQL 并不通用
比如上面的报表,即使 MYSQL 和 ORACLE 的数据结构都相同,也写不出一个可以在两个库都正常工作的 SQL,因为不同的数据库函数有差异,并不全兼容

在 MYSQL 中的取数 SQL 是这样的:

SELECT CHAR(d.订单ID) 订单编号,d.订单金额,d.货主名称,e.雇员ID,
    CONCAT(e.姓氏,e.名字) 姓名,d.订购日期,d.到货日期,e.备注,c.公司名称 
FROM 订单 d,雇员 e,客户表 c 
WHERE  d.雇员ID = e.雇员ID 
    and d.客户ID=c.客户ID 
    and (d.订购日期 between DATE_FORMAT('2012-08-01','%Y-%m-%d') 
    and DATE_FORMAT('2012-08-01','%Y-%m-%d')+INTERVAL 1 MONTH)

而在 ORACLE 中,SQL 是这样:

SELECT CHR(d.订单ID) 订单编号,d.订单金额,d.货主名称,e.雇员ID,
    CONCAT(e.姓氏,e.名字) 姓名,d.订购日期,d.到货日期,e.备注,c.公司名称 
FROM 订单 d,雇员 e,客户表 c
WHERE  d.雇员ID = e.雇员ID 
    and d.客户ID=c.客户ID 
    and (d.订购日期 between TO_DATE('2012-08-01','YYYY-MM-DD') 
    and TO_DATE('2012-08-01','YYYY-MM-DD')+NUMTOYMINTERVAL(1,'MONTH')) 

这两句 SQL 的不同之处有

  1. 两个库对字符串转日期的转换函数不同
  2. 两个库对计算给定日期后增加一个月的日期计算也不同
  3. 数值类型的订单 ID 转为字符串,转换函数也不同

写不出通用的 SQL,那就只能是写两个不同的 SQL,做两个不同的报表了,如果只有一张表需要这样做两次倒也无所谓,但项目上动辄都是几百张报表,如果都做两次,额外的人工成本就会成为一个承受不了的负担,而且相关的维护管理也非常麻烦

润乾报表基于 SPL 提供了脚本数据集,其中有个 sqltranslate 方法,可以将通用的 SQL翻译成适配不同数据库的 SQL,能很好的解决这个难题

实践过程

(1)新建报表模板并制作基本格式

imagepng

(2)增加参数
查询日期:bDate

imagepng

(3)新增、定义脚本数据集,并设置 property,此步骤为关键步骤!!

imagepng

imagepng
脚本文本信息如下:

A B C
1 =connect(“dbConn”) =file(“userDefined.property”).property(“dbType”)
2 =sql=“SELECT CHR(d. 订单 ID) 订单编号,d. 订单金额,d. 货主名称,e. 雇员 ID,CONCAT(e. 姓氏,e. 名字) 姓名,d. 订购日期,d. 到货日期,e. 备注,c. 公司名称 FROM 订单 d, 雇员 e, 客户表 c WHERE d. 雇员 ID = e. 雇员 ID and d. 客户 ID=c. 客户 ID and (d. 订购日期 between DATE(’”+bDate+“‘) and ADDMONTHS(DATE(’”+bDate+“’),1))” / 此步为定义简单 SQL, 其中 DATE、CHR、CONCAT 及 ADDMONTHS 函数为脚本数据集内标准函数
3 =sql.sqltranslate(C1) / 根据实际情况指定数据库类型,将简单 SQL 转化为对应库标准 SQL 语句 /C1:数据库类型信息从配置文件 (userDefined.property) 读取,A3 改为从 C1 查询出的数据
4 =output(“—-:”/A3) / 这里我们输出转化后的 SQL,看是否符合对应库 SQL 标准
5 =A1.query(A3) / 执行 SQL
6 result A5 / 返回给报表结果集

其中:
A2 使用脚本数据集函数写出的通用“简单 SQL”

SELECT CHR(d.订单ID) 订单编号,d.订单金额,d.货主名称,e.雇员ID,
    CONCAT(e.姓氏,e.名字) 姓名,d.订购日期,d.到货日期,e.备注,c公司名称 
FROM 订单 d, 雇员 e, 客户表 c 
WHERE d.雇员ID = e.雇员ID 
    and d.客户ID=c.客户ID 
    and (d.订购日期 between DATE(’”+bDate+“‘) 
    and ADDMONTHS(DATE(’”+bDate+“’),1))

A3 用 sqltranslate 函数,把通用“简单 SQL”翻译成指定数据库的 SQL,具体的数据库类型由 C1 来决定
C1 读取 property 配置文件中的数据库类型配置项,用户需要在 property 中增加 dbType 配置信息(或者新做一个 property 也可以),移植时,只需要把配置文件中的数据库类型改为对应的就可以,然后所有需要切换数据库的报表就都自动切换过来了,不需要单独去改报表或者脚本了

imagepng

imagepng

A4 为转换后 SQL 语句输出,方便我们对比
继续完成报表模板,如下

png

(4)查看翻译结果和报表
A4 脚本单元格,已经把 SQL 翻译结果在后台输出,此处可以看到已转为指定库类型的 SQL

imagepng

imagepng

报表结果如下:

imagepng

(5)切换数据源,移植报表
配置文件中,原先配置的是 MYSQL,需要移植到 ORACLE 时,在配置文件中改成 ORACLE 就可以,然后所有需要移植的报表,就把通用的“简单 SQL”,翻译成 ORACLE 的语句来执行了

切换后,报表呈现 ORACLE 数据:

imagepng

至此,该需求就做完了,原本每个要移植的报表都得做两次,现在一个通用的“简单 SQL”加 sqltranslate 方法,只需要在配置文件里改一下数据库类型,就直接能匹配其他数据库了,确实简单方便了很多

SPL 中已经定义了大部分常见的数据库函数,并且还在不断地追加中,所以大部分的计算都可以搞定了,万一遇上不认识的函数,也支持自定义方式去增加,有需要的可以参考 SPL:跨数据库移植 SQL

不过,这种方法只能对付 SQL 中的函数不同,如果涉及到其他复杂的情况,比如 A 数据库的语法在 B 数据库中彻底就不支持,那就不能用这种办法移植了,这样的情况可以直接用润乾报表的脚本来计算,数据库只要执行最基本的 SQL 用于取数,脚本本身就是超强的计算工具,有很强的计算能力,能直接面对各类数据源进行计算,为报表和前端业务准备数据,用脚本直接走的计算,不仅写的快,算的快,而且不依赖于数据库,天然具有可移植性

总结

润乾报表的通用“简单 SQL”和 sqltranslate 方法,可以很好的解决报表在数据库间移植的难题,尤其是在报表量比较大的时候,这个功能就更加实用,它能省下很多的开发和维护工作,润乾报表很便宜,三万一年随便用,接近于开源软件了,可以很低成本下载实践

以下是广告时间

对润乾产品感兴趣的小伙伴,一定要知道软件还能这样卖哟性价比还不过瘾? 欢迎加入好多乾计划。
这里可以低价购买软件产品,让已经亲民的价格更加便宜!
这里可以销售产品获取佣金,赚满钱包成为土豪不再是梦!
这里还可以推荐分享抢红包,每次都是好几块钱的巨款哟!
来吧,现在就加入,拿起手机扫码,开始乾包之旅



嗯,还不太了解好多乾?
猛戳这里
玩转好多乾