Обработка более 1000 обновлений записей в Spring Hibernate

У меня есть сценарий, в котором мне нужно обновить поле даты для более чем 1000 записей.

Я использовал собственный запрос, но затем получил ошибку ora-01795 maximum number of expressions in a list is 1000.

После проверки я нашел решения, такие как нарушение предложения in, как указано в этот ответ.

Но я нахожу это решение, не очень чистое.

Есть ли другой подход, который я могу использовать в Spring, который немного чище? Пожалуйста, предложите.

Мой текущий запрос выглядит так:

@Modifying
@Query(value = "UPDATE MY_TABLE SET FLAGGED_DATE = :date WHERE ID IN (:ids)", nativeQuery = true)
void updateFlaggedDate(List<Long> ids, Date date);

Идентификаторы, которые я передаю в списке, собираются из стороннего API.


person rahul s    schedule 03.10.2020    source источник
comment
Как бы для вас выглядело чистое решение? У вас должна быть возможность построить оператор SQL where id = :id, а затем запустить пакеты одного и того же оператора SQL с разными значениями переменных связывания из Java. Это не кажется мне более чистым, чем варианты в другом ответе.   -  person Justin Cave    schedule 03.10.2020
comment
Есть несколько вариантов, как это решить: использовать GTT, PTT, PLSQL, JSON или даже MAGIC! Проверьте эту ссылку: asktom.oracle.com/pls/apex/   -  person Bjarte Brandt    schedule 03.10.2020


Ответы (2)


Если вам разрешено создавать новую таблицу, сделайте это как

create table id_list (id number);

Сохраните этот длинный список ID в этой таблице (как? Я не знаю Java, но надеюсь, вы знаете, как это сделать).

Затем используйте его как подзапрос в своем операторе UPDATE как

update my_table set
  flagged_date = :date
where id in (select id from id_list)

Теперь вы не ограничены количеством значений, оно может быть действительно огромным.

person Littlefoot    schedule 03.10.2020

Если вы не против использования PL/SQL, вы можете запустить код, аналогичный приведенному ниже примеру. Это может даже работать лучше, чем ваше исходное обновление, которое вы используете, потому что то, как вы создавали оператор UPDATE, изначально представляет собой другой оператор каждый раз, когда он запускается. Oracle должен был бы придумывать план выполнения каждый раз, когда выполняется запрос, что может быть дорогостоящим. Изменение вашего кода таким образом, чтобы каждый раз запускалось одно и то же UPDATE, поможет оракулу каждый раз использовать один и тот же план выполнения.

DECLARE
    TYPE ids_t IS TABLE OF NUMBER;

    l_ids   ids_t := ids_t ();
BEGIN
    --build up your collection here
    l_ids.EXTEND (3);   --This will be the total number of IDs that you are adding to the collection
    l_ids (1) := 353;
    l_ids (2) := 234;
    l_ids (3) := 123;

    FORALL i IN 1 .. l_ids.COUNT
        UPDATE MY_TABLE
           SET FLAGGED_DATE = :date
         WHERE ID = l_ids (i);
END;
/
person EJ Egyed    schedule 03.10.2020