2012-09-07 20 views
6

Digamos que quiero un JasperReport que permita al usuario filtrar una fecha si así lo desean. El SQL es la siguiente:.Cláusulas condicional Donde en JasperReports

select * from foo where bar = $P{bar} and some_date > $P{some.date} 

Ahora, no quiero para filtrar por una fecha si no pasan a la fecha en que encontré la siguiente kludge que la gente utiliza:

select * from foo where bar = $P{bar} $P!{some.date.fragment} 

y el parámetro some.date.fragment se define con la siguiente defecto:

($P{some.date} == null || $P{some.date}.equals("")) ? "" : "AND some_date >'" + new java.sql.Date($P{some.date}.getTime()).toString() + "'" 

Esto no está funcionando como el toString no da salida a la fecha en un formato que entiende mi servidor SQL. Me gustaría que el condicional siga usando una declaración preparada con el controlador jdbc y arroje el parámetro, solo quiero que la declaración preparada sea dependiente si el parámetro es nulo o no. Se puede hacer esto?

+0

En mi caso, el segundo parámetro era una cadena y la parte de la cláusula where he usado $ P {} stringValue. –

Respuesta

6

Antes de utilizar la expresión $P!{}, el JDBC-Driver hace todo el formateo por usted.

Pero si usa la expresión $P!{}, tiene que formatear usted mismo.

Algo como esto debería funcionar:

(
$P{some.date} == null 
? 
"" 
: 
"AND some_date >'" + (new SimpleDateFormat("dd.MM.yyyy HH:mm:ss.SSS")).format($P{some.date}) + "'" 
) 

Dependiendo de tipo de datos que tiene que personalizar dd.MM.yyyy HH:mm:ss.SSS.

Si no desea utilizar la expresión $P!{}, puede evitarla con la solución a continuación.

Personalmente, no me gusta de esta manera. También puede causar un mal plan de ejecución.

Si no quiere usar $P!{} porque le preocupa la inyección sql. No es necesario siempre que su parámetro $P{some.date} contenga un tipo de datos seguro como java.lang.Date.


Crear un parámetro. Digamos que es ${is_null_pram} y añadir una expresión predeterminada con la clase parámetro Integer:

($P{some.date} == null ? 1 : 0) 

ya se puede consultar:

SELECT 
    * 
FROM foo 
WHERE 
    bar = $P{bar} 
    AND 
     (
      some_date > $P{some.date} 
      OR 1 = $P{is_null_pram} 
     ) 
+0

Bueno, ninguna de esas soluciones es lo que yo quisiera como una solución ideal. Quiero que el parámetro nulo cambie el sql que se está ejecutando, pero también quiero que el controlador jdbc parametrice la entrada.Odio averiguar el formato de fecha, etc. Sin embargo, las segundas opciones parecen mejores, e hice algunas pruebas con el plan de presentación/explicación y las bases de datos manejan el OR apropiadamente al ignorar el predicado si hay una condición verdadera 1 = 1. –

+0

Solo un FYI a cualquiera que vea esto. Haga que 'is_null_param' sea un número entero que compare con otro 1. La comparación de cadenas no se optimiza también en algunas de las bases de datos. –

+0

Jup. Editar hecho Gracias. – edze

1

Creo que se puede utilizar la función:

$X{EQUAL, <column_name>, <parameter_name>}

Optimiza la consulta como se puede ver en la página de ayuda this.

0

Puede utilizar esta sentencia condicional

select * 
    from foo 
    where bar = $P{bar} and some_date > $P{some.date} or $P{some.date} is null 
Cuestiones relacionadas