4

我正在尝试这个查询,但没有成功。

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

此 url 将按 EmployeeID 过滤并正常工作:

.../flow.html?_flowId=viewReportFlow&reportUnit=/reports/samples/EmployeeAccounts&EmployeeID=sarah_id

但是当我删除 EmployeeID 参数时,我想删除过滤器的位置。所以应该显示所有结果。

.../flow.html?_flowId=viewReportFlow&reportUnit=/reports/samples/EmployeeAccounts

我的问题是,在 sql 查询中传递可选 where 的正确方法是什么。

4

2 回答 2

11

好的,让我们看看样本。

例如我们有一个查询:

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参数未定义,则将使用“fake”子句“1=1”,否则将应用按城市字段的过滤器。

当然,我们必须修改查询表达式 - 以使用这个新参数。在这种情况下,我们的查询表达式将是:

<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参数设置芝加哥值,结果将是:

在此处输入图像描述

在这种情况下,引擎使用的查询是:

SELECT id, city, street FROM address WHERE city='Chicago' ORDER BY city

笔记:

  • 您可以在这篇文章中找到更多信息:JasperReports:将参数传递给查询

  • 您可以修改whereClause参数的表达式和查询表达式。例如,您可以将WHERE关键字从查询表达式移动到参数表达式,以防止使用子句“1=1”

于 2013-10-16T18:37:13.013 回答
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 子句条件的情况下为您提供所有值。

于 2013-10-21T07:58:14.523 回答