Ошибка при использовании generate_series в createNativeQuery - PullRequest
1 голос
/ 09 апреля 2019

Запрос на выполнение в базе данных PostgreSQL правильно выбирает записи.Но при реализации с использованием createnativeQuery я получаю сообщение об ошибке

ERROR SqlExceptionHelper:131 - ERROR: syntax error at or near ":"

Запрос, успешно выполненный в базе данных Postgres, упоминается ниже

    select d.dt::date as date_current, 
   coalesce(underwriter_daily_cap, daily_file_cap) as file_cap, 
   user_id 
   from generate_series(date '2019-04-05', date '2019-04-09', interval '1' 
   day) as d(dt)  
     left join (
         select upd.*, ud.daily_file_cap
          from mod_underwriter_daily_file_count upd 
           join lsa_assignment_details ud on ud.user_id = upd.user_id
          where ud.user_id = 350 
         ) upd on upd.date_current = d.dt::date
          ORDER BY d.dt DESC;

Код уровня DAOвыглядит следующим образом:

        @SuppressWarnings("unchecked")
 public List<Object[]> getUnderWriterCap(String dynamicUserId) {
    log.info("Entered UserSkillMappingHibDAO : 
        getUnderWriterCap");
    Session session = sessionFactory.getCurrentSession();
    Date currentDateMinusFive = 
       DateUtil.getLastFiveDayOldPSTDate();
    Date currentDate = DateUtil.getCurrentPSTDate();

    String queryString = " select  d.dt::date as date_current, 
       coalesce(underwriter_daily_cap, daily_file_cap) as file_cap, user_id  " 
                        +" from generate_series ( date '"+DateUtil.getDateFormat(currentDateMinusFive)+"', date '"+DateUtil.getDateFormat(currentDate)+"', INTERVAL '1' DAY ) as d(dt) "  
                        +" left join ( select upd.*, ud.daily_file_cap from mod_underwriter_daily_file_count upd "
                        +" join lsa_assignment_details ud on ud.user_id = upd.user_id  where ud.user_id =  "+ dynamicUserId
                        +") upd on upd.date_current = d.dt::date  ORDER BY d.dt DESC " ; 

            List<Object[]> records = session.createNativeQuery(queryString)
                        .getResultList();

            return records;  

  }

Исключение, полученное в консоли при выполнении вышеуказанного кода, выглядит следующим образом:

Hibernate: выберите d.dt: date в качестве date_current, coalesce (underwriter_daily_cap, daily_file_cap) как file_cap, user_id из generate_series (дата '2019-04-04', дата '2019-04-09', INTERVAL '1' DAY) в качестве d (dt) левого соединения (выберите upd. *, ud.daily_file_cap из mod_underwriter_daily_file_countupd присоединиться: синтаксическая ошибка в или около ":" Позиция: 14

1 Ответ

0 голосов
/ 09 апреля 2019

В этом есть несколько ошибок.Более важным, чем синтаксическая ошибка, является то, как вы добавляете параметр в виде строкового литерала.

Вместо:

session.createNativeQuery("select * from tbl where param = '" + value + "'");

Вы должны использовать подготовленные операторы (это термин для поиска-до).Это чрезвычайно важно для обеспечения безопасности.

Query q = session.createNativeQuery("select * from tbl where param = :par1");
q.setParameter("par1", value);

Теперь, что касается синтаксической ошибки, она вызвана использованием пользовательского синтаксиса преобразования типов PostgreSQL.Вы должны заменить его стандартным типом SQL-запроса от d.dt::date до cast(d.dt as date), потому что Hibernate ожидает, что : будет началом именованного параметра.

String queryString = "select cast(d.dt as date) as date_current, "
                    +" coalesce(underwriter_daily_cap, daily_file_cap) as file_cap, user_id  " 
                    +" from generate_series ( current_date - 5, current_date, INTERVAL '1' DAY ) as d(dt) "  
                    +" left join ( select upd.*, ud.daily_file_cap from mod_underwriter_daily_file_count upd "
                    +" join lsa_assignment_details ud on ud.user_id = upd.user_id  where ud.user_id = :dynuid ) upd on upd.date_current = cast(d.dt as date) ORDER BY d.dt DESC " ; 

List<Object[]> records = session.createNativeQuery(queryString)
                    .setParameter("dynuid", dynamicUserId)
                    .getResultList();

Я также заменил вам текущую дату Javaрасчеты с функциями базы данных.Вместо того, чтобы делать:

Date currentDateMinusFive = DateUtil.getLastFiveDayOldPSTDate();
Date currentDate = DateUtil.getCurrentPSTDate();
...
.setParameter("ds", DateUtil.getDateFormat(currentDateMinusFive))
.setParameter("de", DateUtil.getDateFormat(currentDate))

У вас есть база данных, делающая это за вас, используя current_date - 5 и current_date.

Еще одна вещь, на которую вы должны обратить внимание, так как ваш DateUtil используетстарый класс java.util.Date и связанные с ним вещи заключаются в том, что если вы используете SimpleDateFormatter для его форматирования, то он должен быть новым экземпляром при каждом вызове.Не оптимизируйте его до статического финала, потому что он не потокобезопасен.Я страдал от этого.

edit: Я также считаю, что ваш запрос может быть значительно оптимизирован в этом, и он будет иметь те же результаты:

select upd.date_current, underwriter_daily_cap, daily_file_cap from mod_underwriter_daily_file_count upd
 join lsa_assignment_details ud on ud.user_id = upd.user_id
 where ud.user_id = :dynuid and
 upd.date_current between current_date - 5 and current_date
 ORDER BY d.dt DESC

Обратите внимание, я удалил некоторые поляот выбора, как user_id, потому что вы уже говорите базе данных, какую вы хотите.Единственное существенное отличие состоит в том, что этот запрос будет пропускать результаты для дней без записей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...