2011-12-27 8 views
10

Używam JPQL i chcę zapytać o wartość zerową w długim polu. Ale zawsze otrzymuję ORA-00932: niespójne typy danych: oczekiwany NUMBER ma BINARY. Jak widziałem, jest wiele osób, które mają z tym problemy, ale czy ktoś ma obejście tego problemu?Jak mogę wykonać zapytanie o wartość zerową w długiej wartości bez uzyskania "Oczekiwany NUMBER, ale otrzymałem BINARNY" od OracleDB?

Na przykład jest to zapytanie "SELECT a FROM Auftrag a WHERE :id is null OR a.id = :id" a później Tworzę ID z setParameter("id", null) jest ono używane w bardziej złożonych zapytania do filtrowania cel, tak zerowe oznacza w tym przypadku, aby ignorować filtr na kolumnie.

Ktoś, kto ma pomysł?

Pozdrawiam!

+0

Jak wygląda klasa Auftrag? Również składnia SQL wygląda źle ("gdzie id jest zerowy", NIE "gdzie: id jest zerowy" ...), również, id = null jest również błędną logiką. – someuser2

+0

niezupełnie.po pierwsze nie jest to SQL, ale JPQL (istnieją pewne drobne różnice) i jeśli chcesz ustawić: id na null, a warunek powinien zwracać true, musisz napisać ": id is null". Wynikowa instrukcja będzie w tym przypadku "null is null", a to prawda, więc drugi warunek zostanie zignorowany. – MikeO

+0

Nie sądzę, że twój drugi warunek jest całkowicie ignorowany. Założę się, że wyjątek spowodowany jest porównaniem numerycznego a.id do null (: id) – jan

Odpowiedz

5

Nie znam specyfiki JPQL ani sposobu, w jaki Oracle obsługuje warunek WHERE zapytania. Ale założę się, że druga część waszego warunku WHERE to , który nie został całkowicie zignorowany: i że przyczyną problemu jest a.id = NULL. Oprócz pozornie niespójnych typów danych warunek taki jak some_value = NULL może nie być oceniony jako PRAWDA lub FAŁSZ, ale na NULL (przynajmniej tak się dzieje w PostgreSQL).

EDIT
dla konkretnego przypadku użycia łączny stan :id IS NULL OR a.id = NULL nadal działa zgodnie z przeznaczeniem na PostgreSQL. Ale w innym kontekście nie dostaniesz żadnych wierszy z some_value = NULL, nawet jeśli some_value ma wartość null. Myślę więc, że ze względu na solidny i zrozumiały kod, należy unikać takiego wyrażenia jak some_value = NULL.
END EDIT

może być w stanie obejść problem w JPQL z

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

przynajmniej jest to możliwe z natywnym hibernacji HQL. W tym przypadku druga część warunku WHERE jest równa FALSE, jeśli :id ma wartość null, ale cały warunek WHERE ma wartość TRUE, czyli to, czego chcesz.

Jednak w przypadku zapytań z filtrowaniem dynamicznym lepszym rozwiązaniem byłoby użycie interfejsu API kryteriów JPA 2.0 i uwzględnienie w kwerendzie parametru :id, jeśli nie jest on pusty. Znowu, nie znam szczegółów kryteriów WZP ale z rodzimych Kryteriów Hibernate będzie to

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

nadzieję, że pomoże.

+0

używa null do ingnore części filtrującej. Jeśli: id jest null, otrzyma wybierz coś, co jest prawdziwe, więc nie będzie miał żadnego filtra, a tego właśnie chce. –

+0

@FlorinGhita: Szczerze mówiąc nie wiem, co standard SQL określa w odniesieniu do niektórych _value = NULL' ani jak Oracle to obsługuje, ale przynajmniej w PostgreSQL 9.1 wartość ta jest równa NULL, a nie TRUE/FALSE. A afaik nie ma gwarancji na ocenę zwarcia czegoś takiego jak "TRUE OR ..." w SQL. Uważam, że w każdym razie należy unikać takiego wyrażenia. – tscho

+0

w Oracle null = null jest fałszywe, więc nie powinno to stanowić problemu. –

5

miałem ten sam problem, mam rozwiązać go przez odwrócenie lub ściany, na przykład:

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

nie działa, ale cofa lub boki tak:

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

pracował doskonale. Nie rozumiem dlaczego, ale działa. Prawdopodobnie ma to coś wspólnego z "zwarciem", ale w przypadku wartości zerowej oba stwierdzenia są i tak oceniane. Mam nadzieję, że ktoś może to wyjaśnić.

+1

To działało dla mnie z WaveMaker 6.7. Co tu się dzieje? – anthonybrice

+0

Pracowałem dla mnie. Innym rozwiązaniem, jeśli to możliwe, jest Niższe (wartość pusta). Na przykład. ': id ma wartość NULL LUB DOLNĄ (a.id) = LOWER (: id)' – William

Powiązane problemy