2011-12-27 18 views
10

Estoy usando JPQL y quiero consultar un valor nulo en un campo Largo. Pero siempre obtengo un ORA-00932: tipos de datos inconsistentes: el NUMBER esperado se volvió BINARIO. Como he visto, hay muchas personas que tienen problemas con esto, pero ¿alguien tiene una solución para esto?¿Cómo puedo consultar un nulo en un valor Largo sin obtener "NÚMERO esperado sino OBTENIDO BINARIO" de OracleDB?

Por ejemplo, esta es la consulta "SELECT a FROM Auftrag a WHERE :id is null OR a.id = :id" y más tarde Soy la creación id con setParameter("id", null) .Esta se utiliza en una consulta más compleja para filtrar propósito, por lo que los medios nulos en nuestro caso de ignorar el filtro en la columna.

¿Alguien que tiene una idea?

Saludos cordiales!

+0

¿Cómo es la clase Auftrag? Además, la sintaxis de SQL parece incorrecta ("donde id es nulo", NO "donde: id es nulo" ...), también, id = null también es una lógica incorrecta. – someuser2

+0

no realmente.en primer lugar, esto no es SQL sino JPQL (hay algunas diferencias menores) y si quiere establecer: id a null y la condición debe devolver verdadero, debe escribir ": id is null". La declaración resultante sería "nulo es nulo" en ese caso y esto es cierto, por lo que la segunda condición será ignorada. – MikeO

+0

No creo que su segunda condición sea ignorada por completo. Apuesto a que la excepción es causada por la comparación de la a.id numérica con la nula (: id) – jan

Respuesta

5

No conozco los detalles de JPQL ni cómo maneja Oracle la condición WHERE de su consulta. Pero apostaría a que la segunda parte de su condición WHERE es no ignorada por completo y que a.id = NULL está causando el problema. Aparte de los tipos de datos aparentemente inconsistentes, una condición como some_value = NULL no puede evaluarse como VERDADERO o FALSO sino como NULO (al menos esto sucede en PostgreSQL).

EDITAR
Para su caso de uso específico de la condición combinada :id IS NULL OR a.id = NULL todavía funciona como está previsto en PostgreSQL. Pero en otro contexto, no obtendrá ninguna fila con some_value = NULL, incluso si some_value es nulo. Por lo tanto, creo que, en aras de un código sólido y comprensible, se debe evitar en cualquier caso una expresión como some_value = NULL.
FIN EDITAR

Usted puede ser capaz de solucionar el problema en JPQL con

SELECT a FROM Auftrag a WHERE :id is null OR a.id = COALESCE(:id, -1) 

al menos esto es posible con Hibernate HQL nativa. En este caso, la segunda parte de la condición WHERE se evalúa como FALSE si :id es nulo, pero la condición WHERE completa se evalúa como TRUE, que es lo que desea.

Pero para las consultas de filtrado dinámico, un mejor enfoque sería utilizar la API de criterios de JPA 2.0 e incluir el parámetro :id en la consulta solo si no es nulo. Una vez más, no sé los detalles de los criterios de la APP pero con criterios de Hibernate nativas esto sería

public List<Auftrag> findByFilter(Long id) { 
    Criteria criteria = session.createCriteria(Auftrag.class); 
    if (id != null) { 
    criteria.add(Restrictions.eq("id", id)); 
    } // if 
    return criteria.list(); 
} 

Espero que ayude.

+0

usa null para ocultar la parte filtrante. If: id es nulo, entonces obtendrá seleccione algo donde sea cierto, para que no tenga ningún filtro, y esto es lo que quiere. –

+0

@FlorinGhita: para ser sincero, no sé qué define el estándar SQL con respecto a 'algunos _value = NULL' ni cómo Oracle maneja esto, pero al menos en PostgreSQL 9.1 esto se evalúa a NULL y no a TRUE/FALSE. Y afaik no hay garantía para la evaluación de cortocircuitos de algo así como 'VERDADERO O ...' en SQL. Entonces, creo que tal expresión debería evitarse en cualquier caso. – tscho

+0

en Oracle null = null es falso, por lo tanto, esto no debería ser un problema. –

5

que he tenido el mismo problema, resuelto mediante la inversión o los lados, por ejemplo:

SELECT a 
FROM Auftrag a 
WHERE :id is null OR a.id = :id 

no funcionó, pero invirtiendo o lados así:

SELECT a 
FROM Auftrag a 
WHERE a.id = :id OR :id is null 

trabajaron perfectamente. No entiendo por qué, pero funciona. Probablemente tiene algo que ver con el "cortocircuito", pero en caso de nulo, ambas declaraciones se evalúan de todos modos. Espero que alguien pueda explicar esto.

+1

Esto funcionó para mí con WaveMaker 6.7. ¿Que esta pasando aqui? – anthonybrice

+0

Funcionó para mí. Otra solución, si es posible, es Lower (null). P.ej. ': id es nulo O INFERIOR (a.id) = INFERIOR (: id)' – William

Cuestiones relacionadas