众所周知,大拿们在设计报表的时候,需要展现的数据很少是固定不变地,经常需要使用查询条件过滤出我们想要的数据。简而言之就是,同一张报表可以在不同的参数控制下呈现出不同的数据。

那么问题来了,报表工具一般都用哪些方法来实现这一需求呢?

使用SQL参数

首先当然必须是说 SQL, 正常情况下不同的过滤条件会对应着取数 SQL 中不同的 WHERE 条件,而报表工具能将报表参数对应成 SQL 的参数,这样一来,输入不同报表参数时就会产生不同的 SQL。

假如我们要做一个有查询条件的报表,拿订购日期作为检索条件,查询不同日期区间下订单信息表中的数据。其中的数据列包括:订单 ID, 客户 ID, 订购日期, 发货日期, 运货商, 货主名称, 货主地区, 订单金额。

Follow me,我们拿润乾报表来做个例子,首先设置两个参数,取名为 startdate 与 enddate:

然后这个报表的取数 SQL 要写成含有参数的形式,SQL 语句中使用“?”(英文问号)表示参数:

select 订单 ID, 客户 ID, 订购日期, 发货日期, 运货商, 货主名称, 货主地区, 订单金额 from 订单信息表 where 订购日期 >? and 订购日期 <?

然后要配置 SQL 参数与报表参数的对应,即将 SQL 语句中每个“?”翻译成对应的报表参数。

配置完成后用户只需要通过设置不同的报表参数,就可以获取不同的数据了。例如查询 2014 年 1 月 1 号到 2014 年 1 月 8 号之间的订单信息,那么设置参数 startdate 值为 2014-01-01,参数 enddate 值为 2014-01-08,查询结果如下:

空值参数

有时候我们希望某个参数不输入时报表可以聪明地理解为忽略该参数,比如上例中没有输入 enddate 时报表可以默默地查出从某个起始日期之后的所有订单。那需要怎么做呢?

这种情况下可以把没有输入的参数认为是取值为空的参数,我们只需要修改一下上面的 SQL 语句,增加对空值的判断即可:

select 订单 ID, 客户 ID, 订购日期, 发货日期, 运货商, 货主名称, 货主地区, 订单金额 from 订单信息表 where (? is null or 订购日期 >?) and (? is null or 订购日期 <?)

这样,当参数值为空时就相当于被忽略了。

相应地,SQL 参数与报表参数的对应也要修改,这两个参数在 SQL 中分别使用了两次,各自对应了两个问号:

这时候要查询 2015 年 1 月 1 号之后、结束日期不限制的数据,将参数 startdate 设置为 2015-01-01,参数 enddate 为 null 就可以了,

查询结果如下:

使用宏表达式

从上例可以看到,使用参数时要事先知道取数 SQL 中哪些字段可作为查询条件。但有时候可用于做查询条件的字段非常多,比如针对一个订货信息表来说,还可能按客户 ID、按地区、按运货商等各种条件查询。如果使用上述参数的方式,就需要设置很多的参数,取数 SQL 语句也很长,使用和维护都比较麻烦。如果实现按任意字段查询的话,无疑会方便许多。

有些报表工具提供了宏表达式,可以更灵活地解决这个问题。仍然以润乾报表为例说明:

首先在报表中定义一个字符串参数,比如名称为 search。然后在取数 SQL 中使用宏表达式引用这个参数:

select 订单 ID, 客户 ID, 订购日期, 发货日期, 运货商, 货主名称, 货主地区, 订单金额 from 订单信息表 where ${search}

其中 ${search} 的意思就是会将 search 的内容拼接到 SQL 的相应位置得到一句可执行的 SQL 语句。这种写法即称为宏表达式(下面讨论时就简称宏)。

现在给报表传递不同的参数值就可以得到不同的数据了。例如要查询订单日期为 2014 年 1 月 1 号到 2014 年 1 月 8 号且货主地区为华北的订单信息,那么设置 search 的值为:

订购日期 >’2014-01-01′ and 订购日期 <‘2014-01-08′ and 货主地区 =’华北’

查询结果如下:

从上可以看出利用宏可以在报表中轻易替换 SQL 语句的部分甚至全部,不同参数值,在报表中可以计算出不同的表达式结果,从而得到不同的报表信息,这样面对大量不同类型的报表,用户再也不用每次都做单独的设计和维护了,大大减轻了工作量,释放了劳动力。

参数与宏的对比

既然利用宏可以在报表中动态替换 SQL 语句的部分甚至全部,而且显然使用宏比 SQL 参数更灵活,另外参数能做到的事情用宏都能做到,那么报表工具还有必要提供 SQL 参数机制吗?是不是只要有宏就够了?

事实上并没有这么简单。宏只是简单地替换 SQL 语句的部分,要保证最后的语句合法,有时在生成参数字符串会有麻烦。数值等简单数据类型可以直接拼进 SQL,而字符串常数就需要加上引号才可以,万一这个常数中本身已经有引号,则还需要先进行转义动作,而不同数据库的规则又并不完全一样,这就会影响报表的兼容性。

日期类型参数是最常出现这种麻烦的情况,例如查询订购日期为 2014-12-01 号的订单信息,如果使用 Oracle 数据库,那么宏值写法是:

订购日期 =TO_DATE(‘2014-12-01′,’yyyy-mm-dd’)

如果使用 Mysql 数据库,那么宏值写法为:

订购日期 = DATE_FORMAT(‘2014-12-01′,’yyyy-mm-dd’)

使用 SQL 参数就没有这个问题,数据库接口能直接识别各种数据类型的参数, 直接传入参数值即可,没必要再做这种拼串动作,也就不存在兼容性的问题了。

宏的SQL植入风险

使用宏还存在安全风险,WEB 中使用报表时,参数可能是网页生成并传到后台的,而网页有可能是被黑客攻击改写的,那么就有可能将恶意的参数值传到后台拼入 SQL 语句,欺骗服务器执行恶意 SQL 命令。这就是我们常说的 SQL 植入风险。

比如,在前面的宏表达式示例中,如果有人将 search 值改写成:

1=1 UNION SELECT userid,password,null,… FROM user

那么就可能造成关键信息泄露。解决这个问题并不很简单,把原始 SQL 改写成这样

select … where (${search})

看起来是可以挡住上面那种攻击了,但仍然可以设计出新的植入串攻击(读者有兴趣可以作为一个练习题来试试),要改成为这种很麻烦的样子才行:

select…from…where(${search}) and ${search}

显然,这种语句需要有强烈安全意识的老司机才能做到,而一般报表开发人员这方面相对会弱一些。所以宏不能乱用,能不用则不用。而使用 SQL 参数就没有这个风险,虽然参数没有宏灵活,但显然安全性对报表工具是必不可少的。个别报表工具为了省事只提供宏实现查询条件,看起来是灵活了,但其实是相当不负责任的做法,在选择报表工具时一定要注意。

润乾报表解决方案

如果使用润乾报表,上面的问题就简单多了,润乾报表 5 中新增了对参数检验的功能,这就即可享受宏的灵活性,又能很轻松地挡住这种攻击。仍以上面的业务场景为例,实现步骤如下:

1、制作有宏表达式的报表

在报表中定义一个宏命名为:search,数据集 SQL 为:

select 订单 ID, 客户 ID, 订购日期, 发货日期, 运货商, 货主名称, 货主地区, 订单金额 from 订单信息表 where ${search}

2、配置参数中的禁用单词

在【安装目录】\esProc\config\raqsoftConfig.xml 文件中的 disallowedParamWordList 属性里配置禁用字符串,配置多个字符串时使用逗号分隔,例如

<property name=”disallowedParamWordList” value=”union, user”/>

将会在参数中禁用“union”与“user”,即含有这些串的参数将被拒绝。

3、在 tag 标签上设置检查

用 tag 标签 paramCheck 来控制报表是否要做此校验,paramCheck=”yes”表示接受校验,paramCheck=”no”表示不作校验,不配置该标签时默认为接受校验。这样,不是所有报表都一定会被检查,有些可以确认安全的报表就不必再检查以获得灵活性。

这些都完成后,在 web 端浏览报表时,用户输入的检索条件会在报表参数校验通过后才传递给报表,最终拼接到数据集 SQL 中,不合法的参数值将被拒绝,从而避免了上例中 SQL 植入的风险。

作者:ddszm

链接:http://c.raqsoft.com.cn/article/1533179117653?r=IBelieve

来源:乾学院

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

转载于:https://www.cnblogs.com/IBelieve002/p/9759135.html

报表查询条件的正确打开方式,看到最后不禁会心一下相关推荐

  1. 这才是目前百度统计接口的正确打开方式20180322

    这才是目前百度统计接口的正确打开方式20180322 关于百度统计接口的说明 1.登陆接口网站找到的有2种方式 第一种调用(不能用) https://api.baidu.com/sem/common/ ...

  2. 任务队列和异步接口的正确打开方式(.NET Core版本)

    layout: post title: 任务队列和异步接口的正确打开方式(.NET Core版本) category: dotnet core date: 2019-01-12 tags: dotne ...

  3. 奇门对接需求设计_从2020《奇门遁甲》看网络电影精品化的“正确打开方式”...

    作者 / 1982 "你知道什么是奇门遁甲吗?" 随着2020版网络电影<奇门遁甲>终极预告的神秘发问,观众跟随男主视角一下被带入了那个波云诡谲的东方奇幻世界:雾隐门四 ...

  4. oppo怎么广告接入_OPPO广告分模块投放的正确打开方式

    原标题:OPPO广告分模块投放的正确打开方式 文末有惊喜 期待已久的分模块投放功能即将在OPPO营销平台上线啦!下面蓝莓就先带大家了解OPPO分发广告分模块竞价的相关姿势. what 什么是分模块投放 ...

  5. 软件测试Bug,你是怎么找bug的?bug分析的正确打开方式......

    目录:导读 前言 一. bug详细 二.获取bug具体数据 三.有效的管理bug 四.做好bug分析工作 五.深入bug分析 六.总结 前言 Bug严重级别(Severity,Bug级别):是指因缺陷 ...

  6. 图片压缩的正确打开方式

    图片压缩的正确打开方式 图像通常占据了页面大小的绝大部分,并且占据的绝大部分视觉空间.因此,优化图片通常会节省大量字节数和提升性能:浏览器下载的字节数越少,客户端带宽的争抢越少,浏览器的下载和屏幕加载 ...

  7. c++ 开方_采暖期将至,温尔泰教你壁挂炉采暖前的正确打开方式

    原标题:采暖期将至,温尔泰教你壁挂炉采暖前的正确打开方式 WENETAI 温泰燃气设备/温尔泰壁挂炉 秋天到了,冬天还会远吗 最近一轮接一轮频繁的降温 让很多地方的小伙伴都在准备提前"过冬& ...

  8. Bug深入分析的正确打开方式

    Bug对于测试人员来说是司空见惯的东西,毕竟找到软件的bug就是测试人员工作内容的一部分.但仅仅发现bug是不够的,同时也要避免bug的再次出现,做好软件质量保证工作,所以,做好bug分析就是一件非常 ...

  9. jquery.ztree 打开父节点_增额终身寿险的正确打开方式

    寿险,想必大部分人都理解它的含义:被保人身故或者全残就能获得赔偿的保险,终身寿险自然就是无论何时身故或者全残都会赔偿你的保险.但我们今天要讲的增额终身寿险有点不太一样,它的正确打开方式又是什么呢? 增 ...

最新文章

  1. 【51CTO学院三周年】我的职业生涯有贵人相助--小强老师
  2. ARP监控工具ARPalert常用命令集合大学霸IT达人
  3. 汇编语言--int指令
  4. 【开发技术】视频URL采集
  5. CNN卷积层图像和矩阵转换函数
  6. AliOS Things 硬件抽象层(HAL)对接系列2 — SPI driver porting
  7. mysql 连接池的作用,数据库连接池介绍、主要参数设置、作用
  8. 【AWSL】之Linux管理(RPM)程序
  9. usb连接不上 艾德克斯电源_艾德克斯双范围可编程直流电源IT6800A/B系列
  10. 使用Instant Client配置PL/SQL Developer
  11. 数据库的主键和外键总结
  12. immutability因React官方出镜之使用总结分享!
  13. 复习了C++前几章,做一个ASCII码转换的小程序
  14. Linux下载Mysql
  15. 文档数据库和关系数据库的区别
  16. 软件测试入门理论基础
  17. Win 10提升隐藏性能
  18. Java 移除List中的元素,这玩意讲究!
  19. 如何按数字或者日期时间顺序对多个文件夹进行批量重命名?
  20. 从执行计划的预估行数看执行计划是否正确

热门文章

  1. 一步一步认识用户画像
  2. 一文回顾区块链修订WTO电子商务禁令的影响
  3. 好用的Mac视频下载器:Allavsoft for Mac中文版
  4. mingw64亲测有效版本,直接解压,无需安装
  5. 计算机制造属于连续性生产,生产类型
  6. 论文盲审环节,怎么审?
  7. 手机刷机后数据还在吗?手机刷机并保留数据的方法
  8. Linux Nginx启动报错:Failed at step EXEC spawning /etc/rc.d/init.d/nginx: Exec format error.
  9. 你与心中“小仙女”的距离 只差一个海马体照相馆
  10. 将数组矩阵进行转置,水平镜像,垂直镜像,翻转90°,180°