Распространенное табличное выражение, начинающееся со значения оператора, выдает ошибку в Java - PullRequest
0 голосов
/ 19 декабря 2018

У меня есть этот CTE, который я реализовал бы в Java:
Он работает на компьютере IBM Iseries 7.3 DB2.

WITH params (from_date, to_date, outlet, product_number)
AS (
    values(TO_DATE('01.11.2018', 'DD.MM.YYYY'),
        TO_DATE('18.12.2018', 'DD.MM.YYYY'),
        'BLK' ,
        49 )
    ),
product
AS (
    SELECT DISTINCT cpp.competitor_products_id product
    FROM yxdb.competitor_product_prices cpp
    INNER JOIN yxdb.competitor_products_comparisons cpc ON cpc.competitor_products_id = cpp.competitor_products_id
        AND cpc.deleted = 0
    INNER JOIN yxdb.outlets o ON o.outlets_id = cpc.outlets_id
        AND o.deleted = 0
    INNER JOIN params ON cpp.price_date > params.from_date
        AND cpc.product_number = params.product_number
        AND o.short_name = params.outlet
    WHERE cpp.deleted = 0
    )
select * from product;

Это намного длиннее, поэтому таблица параметров используется несколькораз.
При реализации в Java я заменяю жестко закодированные даты и другие параметры в Java на? 1,? 2 и т. д. Я также пробовал с именованными параметрами, ни один не работает.Все они дают [SQL0418] Use of parameter marker or NULL not valid.

фрагмент кода Java:

@RepositoryRestResource
    public interface CompetitorPriceDateRepository extends JpaRepository<CompetitorPriceDateEntity, Long> {
    @Query(value = "WITH params (from_date, to_date, outlet, product_number) "
                + " AS ( "
                + "     values(TO_DATE( :fromDate , 'DD.MM.YYYY'), "
                + "         TO_DATE( :toDate , 'DD.MM.YYYY'), "
                + "         :outlet , "
                + "         :productNumber ) "
                + "     ), "
                + " product "
                + " AS ( "
                + "     SELECT DISTINCT cpp.competitor_products_id product "
                + "     FROM yxdb.competitor_product_prices cpp "
                + "     INNER JOIN yxdb.competitor_products_comparisons cpc ON +" cpc.competitor_products_id = cpp.competitor_products_id "
                + "         AND cpc.deleted = 0 "
                + "     INNER JOIN yxdb.outlets o ON o.outlets_id = cpc.outlets_id "
                + "         AND o.deleted = 0 "
                + "     INNER JOIN params ON cpp.price_date > params.from_date "
                + "         AND cpc.product_number = params.product_number "
                + "         AND o.short_name = params.outlet "
                + "     WHERE cpp.deleted = 0 "
                + "     ) "
                + " select * from product ",nativeQuery = true) 
    List<CompetitorPriceDateEntity> findAllInterpolatedByDates(
                    @Param("productNumber") Integer productNumber,
                    @Param("outlet") String outlet,
                    @Param("fromDate") String fromDate,
                    @Param("toDate") String toDate
            );

1 Ответ

0 голосов
/ 19 декабря 2018

Без трассировки стека у меня нет никакой информации о том, что не так с вашим запросом.SQL кажется надежным.

Попробуйте использовать именованный собственный запрос

@Entity
@NamedNativeQuery(
        name = “competitor.findProducts.byDateOutletProductnumber", 
        query = "WITH params (from_date, to_date, outlet, product_number) "
            + " AS ( "
            + "     values(TO_DATE( :fromDate , 'DD.MM.YYYY'), "
            + "         TO_DATE( :toDate , 'DD.MM.YYYY'), "
            + "         :outlet , "
            + "         :productNumber ) "
            + "     ), "
            + " product "
            + " AS ( "
            + "     SELECT DISTINCT cpp.competitor_products_id product "
            + "     FROM yxdb.competitor_product_prices cpp "
            + "     INNER JOIN yxdb.competitor_products_comparisons cpc ON +" cpc.competitor_products_id = cpp.competitor_products_id "
            + "         AND cpc.deleted = 0 "
            + "     INNER JOIN yxdb.outlets o ON o.outlets_id = cpc.outlets_id "
            + "         AND o.deleted = 0 "
            + "     INNER JOIN params ON cpp.price_date > params.from_date "
            + "         AND cpc.product_number = params.product_number "
            + "         AND o.short_name = params.outlet "
            + "     WHERE cpp.deleted = 0 "
            + "     ) "
            + " select * from product ", 
        hints = { 
            @QueryHint(name = "org.hibernate.cacheable", value = "true") })
public class CompetitorPriceDateEntity { ... }

pro bonus 1: Именованные запросы являются своего рода предварительно скомпилированными, поэтому jpa не нужно компилировать запрос в исполняемые критериикаждый раз, когда его вызывают.

профессиональный бонус 2: кеширование запроса или эквивалентная затмение

...