СЛУЧАЙ запроса JPQL, когда всегда false

#java #mysql #sql #spring #jpa

#java #mysql #sql #весна #jpa

Вопрос:

Привет, у меня есть длинный запрос для приложения spring, java 8, hibernate, mysql, которое работает должным образом, за исключением последней части, которая суммирует зарезервированные элементы в хранилище:

 SELECT new example.package.RaktarKimutatasDTO(rk.cikkId.cikkName, 
CONCAT(SUM(rk.mennyisegMe1),' ', rk.me1.unitCode, ' / ', SUM(rk.mennyisegMe2),' ', rk.me2.unitCode, ' / ', SUM(rk.mennyisegMe3),' ', rk.me3.unitCode), 
CONCAT(AVG(rk.listaar), ' Ft'), 
CONCAT(rk.mennyisegMe1*rk.listaar, ' Ft'), 
rk.raktarId.raktarNeve, rk.cikkId.vtsz.vatCode, 
SUM(CASE WHEN rk.vevoiEntity IS NOT NULL THEN rk.mennyisegMe1 ELSE 0.0 END)) 
FROM RaktarkeszletEntity rk 
WHERE rk.raktarId.identifier IN ?1 AND rk.createDate<?2 AND (rk.bejovoszamlaEntity LIKE 'RB%' OR (rk.bejovoszamlaEntity LIKE 'BM%' AND rk.bevetel = TRUE)) 
GROUP BY rk.cikkId
 

Проблема в том, что часть SUM(CASE … ) всегда возвращает 0.
Хотя, если я использую (почти) тот же запрос в обычном SQL, из Mysql workbench, он работает, как и ожидалось, суммирует количества для элементов, которые имеют значение «vevoiEntity», которое не равно null (таким образом, зарезервированное количество).
Поле vevoiEntity в БД имеет тип int, который также может быть null .

Поля, называемые entity (за исключением, конечно, которые используются в FROM ), являются не сущностями, а простым целым числом. (у предыдущего разработчика тоже были проблемы с именованием).

Я пробовал использовать больше круглых скобок, пробовал «<> NULL», пробовал «vevoiEntity> 0» и т. Д., Но ничего не помогло, случай всегда false, все остальные части идеальны.

Почему это работает по-разному в native SQL и JPQL? Я установил hibernate.show_sql=true, и я увидел, что сгенерированный запрос для части SUM CASE похож на запрос, который я использовал в workbench, поэтому перевод, похоже, в порядке.

обычный SQL (уже рабочие части опущены), который работает:

 SELECT rk.cikk_id, SUM(CASE WHEN rk.vevoi_tetel_id IS NOT NULL THEN rk.mennyiseg_me_1 ELSE 0 END) as reserved  FROM nast_raktarkeszlet rk GROUP BY rk.cikk_id;
 

или:

 SELECT rk.cikk_id, CONCAT(SUM(rk.mennyiseg_me_1),' ', rk.me_1, ' / ', SUM(rk.mennyiseg_me_2),' ', rk.me_2, ' / ', SUM(rk.mennyiseg_me_3),' ', rk.me_3), CONCAT(AVG(rk.listaar), ' Ft'), CONCAT(rk.mennyiseg_me_1*rk.listaar, ' Ft'), rk.raktar_id, rk.cikk_id, SUM(CASE WHEN IFNULL(rk.vevoi_tetel_id, 0) >0 THEN rk.mennyiseg_me_1 ELSE 0 END) FROM nast_raktarkeszlet rk GROUP BY rk.cikk_id
 

сгенерированный запрос:

 select
        basecikkek1_.cikk_name as col_0_0_,
        concat(sum(rak0_.mennyiseg_me_1),
        ' ',
        men2_.unit_code,
        ' / ',
        SUM(rak0_.mennyiseg_me_2),
        ' ',
        men3_.unit_code,
        ' / ',
        SUM(rak0_.mennyiseg_me_3),
        ' ',
        men4_.unit_code) as col_1_0_,
        concat(avg(rak0_.listaar),
        ' Ft') as col_2_0_,
        concat(rak0_.mennyiseg_me_1*rak0_.listaar,
        ' Ft') as col_3_0_,
        rak5_.raktar_name as col_4_0_,
        vts7_.vat_code as col_5_0_,
        sum(case 
            when rak0_.szallitolevel_tetel_id is not null 
            or rak0_.kimeno_tetel_id is not null 
            or rak0_.vevoi_tetel_id<>0 then rak0_.mennyiseg_me_1 
            else 0 
        end) as col_6_0_ 
    from
        nast_raktarkeszlet rak0_ cross 
    join
        nast_cikkek basecikkek1_ cross 
    join
        nast_vtsz vts7_ cross 
    join
        nast_units men2_ cross 
    join
        nast_units men3_ cross 
    join
        nast_units men4_ cross 
    join
        nast_raktarak rak5_ 
    where
        rak0_.cikk_id=basecikkek1_.id 
        and basecikkek1_.vtsz=vts7_.id 
        and rak0_.me_1=men2_.id 
        and rak0_.me_2=men3_.id 
        and rak0_.me_3=men4_.id 
        and rak0_.raktar_id=rak5_.id 
        and (
            rak0_.raktar_id in (
                ? , ? , ? , ?
            )
        ) 
        and rak0_.create_date<? 
        and (
            rak0_.parentid like 'RB%' 
            or (
                rak0_.parentid like 'BM%'
            ) 
            and rak0_.bevetel=1
        ) 
    group by
        rak0_.cikk_id
 

Комментарии:

1. В любое время, когда NULL используется в вычислении или конкате (или любой функции) для любого поля, весь результат будет нулевым. Все ли значения, которые вы используете в своих формулах, НЕ РАВНЫ НУЛЮ? Если нет, введите ISNULL(значение, «) (или 0, если число и так далее)

2. Покажите SQL, который затем генерируется, а также то, что вы используете, что работает. Возможно, вы захотите упростить запрос, чтобы протестировать оператор case, а затем создать его обратно, чтобы увидеть, какая часть может вызывать проблемы для этого оператора case

3. СУММА (СЛУЧАЙ, КОГДА ISNULL(rk.vevoiEntity,0)>0, ЗАТЕМ rk.mennyisegMe1, ИНАЧЕ 0 END) приводит к исключению во время выполнения com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: неправильное количество параметров при вызове встроенной функции ‘ISNULL’

4. Я вижу, что для mysql следует использовать IFNULL, поэтому ошибки нет, просто обычный результат 0…

Ответ №1:

БОЖЕ, мой плохой. Условия WHERE исключают записи, которые имеют ненулевую «vevoientity»