我正在尝试此查询,但没有成功。
SELECT name, phone_office, billing_address_city, billing_address_street, billing_address_country
FROM accounts
WHERE ($P!{EmployeeID} is null or assigned_user_id = $P!{EmployeeID})
ORDER BY billing_address_country, billing_address_city
此网址将按EmployeeID进行过滤,工作正常:
.../flow.html?_flowId=viewReportFlow&reportUnit=/reports/samples/EmployeeAccounts&EmployeeID=sarah_id
但是当我删除EmployeeID参数时,我想删除过滤器所在的位置。所以应该显示所有结果。
.../flow.html?_flowId=viewReportFlow&reportUnit=/reports/samples/EmployeeAccounts
我的问题是,在sql查询中传递可选where的正确方法是什么。
答案 0 :(得分:9)
好的,让我们看看样本。
例如我们有一个查询:
SELECT id, city, street FROM address WHERE city=$P{inputParamCity} ORDER BY city
但我们的 inputParamCity 可以是未定义的。在这种情况下,我们得到一个错误:
Error filling print... Error preparing statement for executing the report query :
SELECT id, city, street FROM address WHERE city=? ORDER BY city
我们如何解决? 这很简单 - 我们可以使用默认表达式添加另一个参数,如下所示:
<parameter name="whereClause" class="java.lang.String" isForPrompting="false">
<defaultValueExpression><![CDATA[()$P{inputParamCity} == null || $P{inputParamCity}.isEmpty()) ? "1=1" : "city='" + $P{inputParamCity} + "'"]]></defaultValueExpression>
</parameter>
- 如果 inputParamCity 参数未定义,将使用“假”子句“1 = 1”,在其他情况下, city 字段将被应用。
当然我们必须修改查询表达式 - 使用这个新参数。在这种情况下,我们的查询表达式将是:
<queryString>
<![CDATA[SELECT id, city, street FROM address WHERE $P!{whereClause} ORDER BY city]]>
</queryString>
jrxml 文件:
<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="optional_where_clause" language="groovy" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="d3648644-0087-4dfc-ac6d-87e82d9bb33e">
<parameter name="inputParamCity" class="java.lang.String"/>
<parameter name="whereClause" class="java.lang.String" isForPrompting="false">
<defaultValueExpression><![CDATA[($P{inputParamCity} == null || $P{inputParamCity}.isEmpty()) ? "1=1" : "city='" + $P{inputParamCity} + "'"]]></defaultValueExpression>
</parameter>
<queryString>
<![CDATA[SELECT id, city, street FROM address WHERE $P!{whereClause} ORDER BY city]]>
</queryString>
<field name="ID" class="java.lang.Integer"/>
<field name="CITY" class="java.lang.String"/>
<field name="STREET" class="java.lang.String"/>
<detail>
<band height="20" splitType="Stretch">
<textField>
<reportElement uuid="c2a80b99-e087-4839-8e77-841edd899255" x="0" y="0" width="100" height="20"/>
<textElement/>
<textFieldExpression><![CDATA[$F{ID}]]></textFieldExpression>
</textField>
<textField>
<reportElement uuid="0aafcfd6-60f7-4272-8e7d-0aa77507204b" x="100" y="0" width="100" height="20"/>
<textElement/>
<textFieldExpression><![CDATA[$F{CITY}]]></textFieldExpression>
</textField>
<textField>
<reportElement uuid="c8726513-8250-43ec-bafc-003e81094c27" x="200" y="0" width="100" height="20"/>
<textElement/>
<textFieldExpression><![CDATA[$F{STREET}]]></textFieldExpression>
</textField>
</band>
</detail>
</jasperReport>
如果使用未定义的 inputParamCity 参数(未设置该值),结果将为:
在这种情况下,引擎使用的查询是:
SELECT id, city, street FROM address WHERE 1=1 ORDER BY city
如果我们为 inputParamCity 参数设置值 Chicago ,结果将为:
在这种情况下,引擎使用的查询是:
SELECT id, city, street FROM address WHERE city='Chicago' ORDER BY city
备注:强>
您可以在此信息中找到更多信息:JasperReports: Passing parameters to query
您可以修改 whereClause 参数的表达式和查询表达式。例如,您可以将 WHERE 关键字从查询表达式移动到参数的表达式,以防止使用假子句 “1 = 1”
答案 1 :(得分:2)
我认为也可以用这种方式完成可选的where子句: -
SELECT name, phone_office,
billing_address_city, billing_address_street,
billing_address_country
FROM accounts
WHERE (assigned_user_id = $P{EmployeeID} or $P{EmployeeID} is null)
ORDER BY billing_address_country, billing_address_city
在这种情况下,如果您没有传递任何员工ID,它会为您提供所有值而不应用where子句条件。