如果不输入参数,则忽略where子句中的日期范围参数。对于我的日期范围即时通讯使用之间。
这些参数是从jasper报告中输入的
functionA
如果未输入日期,则报告应携带任何日期的记录,因为未输入日期范围
答案 0 :(得分:0)
您有两种方法来处理可选的输入参数。
简单方法是使用静态SQL并为缺少的参数提供 default 值,以便获得所有匹配项。
您在这里简单地将边界设置为最小和最大DATE。
select *
from customer
where customer_id = $P{CLIENT_ID}
and datetrx between nvl($P{DATE_START},date'1900-01-01')
and nvl($P{DATE_END},date'2200-01-01')
更高级的 方法已被Tom Kyte所流行,并且是基于使用动态SQL的。
如果提供了参数,您将使用BETWEEN
谓词生成普通SQL:
select *
from customer
where customer_id = $P{CLIENT_ID}
and datetrx between $P{DATE_START} and $P{DATE_END}
如果缺少参数(即传递了NULL
),则会生成不同的SQL ,如下所示。
select *
from customer
where customer_id = $P{CLIENT_ID}
and (1=1 or datetrx between $P{DATE_START} and $P{DATE_END})
请注意,
1)查询的两个变体中绑定变量的数量相同,这很重要,因为您可以使用相同的setXXXX
语句
2)由于快捷方式 1 = 1 or
被忽略了between
谓词,即考虑了所有日期。
应使用哪个选项?
对于简单查询而言,差异很小,但是对于具有缺失参数和大数据的几种选择的复杂查询,首选动态SQL方法。
原因是,使用静态SQL时,同一条语句用于更多不同的查询-这里一个用于访问 数据范围,而另一个用于访问无数据范围。
dynamic选项为每次访问生成不同的SQL。
您可能会在execution plans上看到它:
按日期范围访问
-------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 22 | 1 (0)| 00:00:01 |
|* 1 | FILTER | | | | | |
|* 2 | INDEX RANGE SCAN| CUST_IDX1 | 1 | 22 | 1 (0)| 00:00:01 |
-------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter(TO_DATE(:1)<=TO_DATE(:2))
2 - access("CUSTOMER_ID"=1 AND "DATETRX">=:1 AND "DATETRX"<=:2)
无数据访问范围
------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 22 | 1 (0)| 00:00:01 |
|* 1 | INDEX RANGE SCAN| CUST_IDX1 | 1 | 22 | 1 (0)| 00:00:01 |
------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("CUSTOMER_ID"=1)
两个语句都产生不同的执行计划,该计划针对输入参数进行了优化。在静态选项中,必须对所有可能引起问题的输入共享相同的执行计划。