Существует ли эквивалентное предложение в спящем режиме для Oracle 12c's & ldquo; fetch first & hellip; & rdquo; статья? [Дубликат]

Продолжение вкладов Брандона Бертельсена в Rcpp. Для меня версия NumericVector не работала: она заменила только первое NA. Это связано с тем, что вектор ina оценивается только один раз в начале функции.

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

library(Rcpp)
cppFunction('NumericVector na_locf_numeric(NumericVector x) {
  R_xlen_t n = x.size();
  for(R_xlen_t i = 0; i<n; i++) {
    if(i > 0 && !R_finite(x[i]) && R_finite(x[i-1])) {
      x[i] = x[i-1];
    }
  }
  return x;
}')

Если вам нужна версия CharacterVector, то работает тот же базовый подход:

cppFunction('CharacterVector na_locf_character(CharacterVector x) {
  R_xlen_t n = x.size();
  for(R_xlen_t i = 0; i<n; i++) {
    if(i > 0 && x[i] == NA_STRING && x[i-1] != NA_STRING) {
      x[i] = x[i-1];
    }
  }
  return x;
}')
195
задан Peter Mortensen 21 December 2015 в 11:01
поделиться

9 ответов

Это было опубликовано на форуме Hibernate несколько лет назад, когда его спросили о том, почему это сработало в Hibernate 2, но не в Hibernate 3:

Предел был never поддерживаемое предложение в HQL. Вы должны использовать setMaxResults ().

Так что если он работал в Hibernate 2, кажется, это было по совпадению, а не по дизайну. Я думаю, что это было потому, что парсер Hibernate 2 HQL заменил бит запроса, который он распознал как HQL, и оставил все остальное как есть, чтобы вы могли прокрасться в какой-то собственный SQL. Hibernate 3, однако, имеет правильный алгоритм AST HQL, и он намного менее прощает.

Я думаю, что Query.setMaxResults() действительно является вашим единственным вариантом.

270
ответ дан skaffman 18 August 2018 в 02:41
поделиться
  • 1
    Я бы сказал, что подход Hibernate 3 более правильный. Ваше использование Hibernate означает агностикцию базы данных, поэтому вам придется делать эти вещи абстрактным образом. – matt b 6 August 2009 в 17:35
  • 2
    Я согласен, но это делает миграцию королевской болью в заднице, когда функции отбрасываются именно так. – skaffman 6 August 2009 в 17:38
  • 3
    но с setMaxResults запускается первый запрос, а затем на наборе результатов, который вы вызываете setMaxResults, который будет принимать ограниченное количество строк результатов из набора результатов и отображать его пользователю, в моем случае у меня есть 3 миллиона записей, которые запрашиваются, а затем я вызываю setMaxResults установить 50 записей, но я не хочу этого делать, а сам запрос я хочу запросить 50 записей, есть ли способ сделать это? – Rachel 27 January 2012 в 22:06
  • 4
    Старый пост я знаю. Я полностью согласен с Рэйчел. Используя NHibernate (.Net-порт Hibernate), я недавно обновил от 2 до 3 и то же самое, верхний X теперь бросает ошибку парсера. Однако, когда я добавил setMaxResults в запрос, он создал TOP X в результате SQL (используя MsSql2008Dialect). Это хорошо. – Thierry_S 4 November 2013 в 19:00
  • 5
    @Rachel С помощью setMaxResults hibernate добавит часть limit к запросу. Он не получит всех результатов. Вы можете проверить полученный запрос, включив: <property name="show_sql">true</property> – Andrejs 23 December 2014 в 10:55
 // SQL: SELECT * FROM table LIMIT start, maxRows;

Query q = session.createQuery("FROM table");
q.setFirstResult(start);
q.setMaxResults(maxRows);
123
ответ дан Jessu 18 August 2018 в 02:41
поделиться
  • 1
    Мне нравится это лучше всего, потому что в этом ответе фактически упоминается setFirstResult, тогда как здесь и в другом месте они просто говорят setMaxResults this и setMaxResults, что без упоминания о том, как установить смещение. – demongolem 1 August 2014 в 21:27

Если вы не хотите использовать setMaxResults() в объекте Query, вы всегда можете вернуться к использованию обычного SQL.

16
ответ дан pjp 18 August 2018 в 02:41
поделиться
  • 1
    На самом деле это не так захватывающе. – stevedbrown 6 August 2009 в 16:39
  • 2
    Я тоже не считаю HQL захватывающим. Почему бы не написать представление на вашем сервере БД, которое применяет предел, а затем заставить HQL посмотреть на это представление: P – pjp 6 August 2009 в 16:59
  • 3
    Это всего лишь одна из тех вещей, в то время как SQL намного проще, чем HQL для каждого запроса, создание представлений и запись родного SQL, как правило, не так хороши для рефакторинга. Я стараюсь избегать этого, когда смогу. Эта реальная проблема заключалась в том, что я написал свой MySQL-запрос в любом случае, и мысль setMaxResults была странной. Это не так. – stevedbrown 6 August 2009 в 17:07

Если вы можете управлять лимитом в этом режиме

public List<ExampleModel> listExampleModel() {
    return listExampleModel(null, null);
}

public List<ExampleModel> listExampleModel(Integer first, Integer count) {
    Query tmp = getSession().createQuery("from ExampleModel");

    if (first != null)
        tmp.setFirstResult(first);
    if (count != null)
        tmp.setMaxResults(count);

    return (List<ExampleModel>)tmp.list();
}

Это действительно простой код для обработки лимита или списка.

2
ответ дан alexandrum 18 August 2018 в 02:41
поделиться

String hql = "select userName from AccountInfo order by points desc 5";

Это работало для меня без использования setmaxResults();

Просто укажите максимальное значение в последнем (в данном случае 5) без использования ключевого слова limit , : Р [/ д2]

4
ответ дан Casey 18 August 2018 в 02:41
поделиться
  • 1
    Хм ... не слишком уверен в этом, [править] это может быть несчастным случаем и может внезапно перестать работать в новой версии спящего режима. – Konrad 'ktoso' Malawski 15 March 2011 в 18:29
  • 2
    Пожалуйста, обратитесь к официальному документу. – Do Nhu Vy 22 January 2016 в 05:11
Criteria criteria=curdSession.createCriteria(DTOCLASS.class).addOrder(Order.desc("feild_name"));
                criteria.setMaxResults(3);
                List<DTOCLASS> users = (List<DTOCLASS>) criteria.list();
for (DTOCLASS user : users) {
                System.out.println(user.getStart());
            }
0
ответ дан Deep Chand Jaipur 18 August 2018 в 02:41
поделиться

Если вы не хотите использовать setMaxResults, вы также можете использовать Query.scroll вместо списка и извлекать нужные строки. Полезно для подкачки, например.

5
ответ дан Lluis Martinez 18 August 2018 в 02:41
поделиться
  • 1
    Спасибо, принятый ответ не разрешил проблему для меня, потому что setMaxResults() загружает первую каждую запись в память, а затем создает подсписку, которая, когда сто тысяч или более записей сбрасывает сервер, потому что у него не хватает памяти. Тем не менее я мог перейти от запрошенного JPA запроса к запросу Hibernate через QueryImpl hibernateQuery = query.unwrap(QueryImpl.class), а затем я мог бы использовать метод scroll(), как вы предложили. – toongeorges 21 June 2017 в 14:59
  • 2
    По крайней мере, с диалектом Oracle это неверно (Hibernate использует виртуальный столбец ROWNUM). Возможно, это зависит от водителя. Другие DB имеют функцию TOP. – Lluis Martinez 22 June 2017 в 11:55
  • 3
    В моем запросе используется выбор извлечения. Это приводит к предупреждению Hibernate "firstResult / maxResults, указанному с помощью коллекции fetch; применение в памяти ". Таким образом, при извлечении соединения Hibernate загружает полную коллекцию в память. Отключение соединения не является вариантом из-за причин производительности. Когда я использую ScrollableResults, я больше контролирую, какие записи загружаются в память. Я не могу загрузить все записи с помощью Single ScrollableResults, потому что это также приводит к нехватке памяти. Я экспериментирую с загрузкой нескольких страниц с помощью разных прокручиваемых результатов. Если это не сработает, я поеду с SQL. – toongeorges 22 June 2017 в 12:52
  • 4
    Это странно, я никогда не сталкивался с этим. Да, иногда использование прямого JDBC - это путь, особенно для массовых / пакетных процессов. – Lluis Martinez 22 June 2017 в 14:35
  • 5
    Отношения @OneToMany вызывают мои проблемы. Если каким-то образом я мог бы выполнить агрегированную функцию Oracle LISTAGG в Hibernate, чтобы объединить несколько значений в одно значение, тогда я могу удалить соединения и заменить их на подзапрос. – toongeorges 22 June 2017 в 15:13

Вам нужно написать собственный запрос, this .

@Query(value =
    "SELECT * FROM user_metric UM WHERE UM.user_id = :userId AND UM.metric_id = :metricId LIMIT :limit", nativeQuery = true)
List<UserMetricValue> findTopNByUserIdAndMetricId(
    @Param("userId") String userId, @Param("metricId") Long metricId,
    @Param("limit") int limit);
0
ответ дан swatisinghi 18 August 2018 в 02:41
поделиться

Мое замечание состоит в том, что даже у вас есть ограничение в HQL (hibernate 3.x), это либо приведет к ошибке синтаксического анализа, либо просто игнорируется. (если у вас есть заказ от + desc / asc до предела, он будет проигнорирован, если у вас нет desc / asc до предела, это вызовет ошибку синтаксического анализа)

1
ответ дан Xingsheng 18 August 2018 в 02:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: