2011-12-27 18 views
10

Sto usando JPQL e voglio interrogare per un valore nullo in un campo lungo. Ma ottengo sempre un ORA-00932: tipi di dati incoerenti: il NUMBER previsto è BINARIO. Come ho visto ci sono molte persone che hanno problemi con questo, ma qualcuno ha una soluzione per questo?Come posso interrogare un valore null in un valore Long senza ottenere "Expected NUMBER ma ottenuto BINARY" da OracleDB?

Per esempio, questo è la query "SELECT a FROM Auftrag a WHERE :id is null OR a.id = :id" e poi sto modificando id con setParameter("id", null) .Questo viene utilizzato in una query più complessa per il filtraggio scopo, mezzi così nulli nel nostro caso di ignorare il filtro sulla colonna.

Chiunque abbia un'idea?

Cordiali saluti!

+0

come è la classe Auftrag? Inoltre, la sintassi SQL sembra errata ("dove id è null", NOT "dove: id è null" ...), anche, id = null è anche la logica sbagliata. – someuser2

+0

non proprio.prima di tutto questo non è SQL ma JPQL (ci sono alcune piccole differenze) e se vuoi impostare: id su null e la condizione dovrebbe restituire true devi scrivere ": id is null". L'affermazione risultante sarebbe "null is null" in questo caso e questo è vero, quindi la seconda condizione verrà ignorata. – MikeO

+0

Non penso che la tua seconda condizione sia completamente ignorata. Scommetto che l'eccezione è causata dal confronto del valore numerico da a.id a null (: id) – jan

risposta

5

Non conosco le specifiche di JPQL né il modo in cui Oracle gestisce la condizione WHERE della query. Ma scommetto che la seconda parte della tua condizione WHERE è non completamente ignorata e che lo a.id = NULL causa il problema. A parte i tipi di dati apparentemente incoerenti, una condizione come some_value = NULL potrebbe non essere valutata su VERO o FALSO ma su NULL (almeno su PostgreSQL).

EDIT
Per il vostro caso specifico uso la condizione combinato :id IS NULL OR a.id = NULL funziona ancora come previsto su PostgreSQL. Ma in un altro contesto non si otterrà alcuna riga con some_value = NULL anche se some_value è nullo. Quindi penso che per il codice robusto e comprensibile un'espressione come some_value = NULL dovrebbe essere evitata in ogni caso.
FINE EDIT

Potreste essere in grado di aggirare il problema in JPQL con

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

almeno questo è possibile con nativo Hibernate HQL. In questo caso la seconda parte della condizione WHERE restituisce FALSE se :id è null ma l'intera condizione WHERE restituisce TRUE, che è ciò che si desidera.

Ma per le query di filtro dinamico un approccio migliore sarebbe utilizzare l'API dei criteri JPA 2.0 e includere il parametro :id nella query solo se non è nullo. Ancora una volta, non so le specifiche di criteri di APP, ma con criteri di Hibernate nativi questo sarebbe

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(); 
} 

Speranza che aiuta.

+0

che usa null per ingnorare la parte filtrante.Se: id è null allora otterrà selezionare qualcosa dove è vero, quindi non avrà alcun filtro, e questo è quello che vuole. –

+0

@FlorinGhita: Ad essere onesti non so cosa definisce lo standard SQL riguardo ad alcuni _value = NULL' né come Oracle gestisce questo, ma almeno su PostgreSQL 9.1 questo vale NULL e non TRUE/FALSE. Inoltre, non vi è alcuna garanzia per la valutazione del cortocircuito di qualcosa come "VERO O ..." in SQL. Quindi, penso che una tale espressione dovrebbe essere evitata in ogni caso. – tscho

+0

in Oracle null = null è falso, quindi, questo non dovrebbe essere un problema. –

5

Ho avuto lo stesso problema, ho risolto invertendo OR lati, ad esempio:

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

non funzionava, ma invertendo O parti simili:

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

lavorato perfettamente. Non capisco perché, ma funziona. Probabilmente ha qualcosa a che fare con il "cortocircuito", ma in caso di null entrambe le affermazioni vengono valutate comunque. Spero che qualcuno possa spiegarlo.

+1

Questo ha funzionato per me con WaveMaker 6.7. Che cosa sta succedendo qui? – anthonybrice

+0

ha funzionato per me. Un'altra soluzione, se possibile, è Lower (il null). Per esempio. ': id è null O LOWER (a.id) = LOWER (: id)' – William

Problemi correlati