Как можно избежать дублирования значений при загрузке данных с использованием весеннего пакетного задания? - PullRequest
0 голосов
/ 23 апреля 2019

У меня есть подпружиненная программа, которая считывает данные из одной базы данных, затем обрабатывает их, а затем записывает в базу данных Oracle. Эта пакетная программа запускается по расписанию один раз в день. Как можно избежать добавления одной и той же записи при каждом запуске и только новых значений из исходной БД?

Ответы [ 4 ]

1 голос
/ 24 апреля 2019

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

Да, и - поместите уникальный первичный ключ в свои таблицы. Все они. Даже те, где вы не думаете, что вам это нужно. Первичный ключ, который вы добавляете сегодня, это тот, на котором вы не скажете позже: «Черт. Я бы хотел, чтобы у таблицы был первичный ключ». Не спрашивайте меня, откуда я знаю ...

Удачи.

1 голос
/ 23 апреля 2019

Одним из вариантов является создание уникального индекса (или первичного ключа, если это возможно (в зависимости от того, хотите ли вы разрешить нулевые значения или нет)), который заставит Oracle автоматически отклонять все строки, столбцы которых нарушают уникальность.

Для других опций требуется некоторое программирование.

[ПРАВКА: пропустить ошибки "без вывода сообщений»]

Вот что я имел в виду:

for cur_r in (select col1, col2
              from another_table@db_link)
loop
  begin        --> you need inner BEGIN-EXCEPTION-END block
    insert into new_table (col1, col2)
      values (cur_r.col1, cur_r.col2);
  exception
    when dup_val_on_index then
      null;
  end;
end loop;

В другом варианте используется чистый SQL (т. Е. Без PL / SQL loop ):

insert into new_table (col1, col2)
  select col1, col2
  from another_table@db_link
  where (col1, col2) not in (select col1, col2 
                             from new_table);

Этот параметр даже не требует уникального индекса (что не повредит, хотя), поскольку NOT IN не будет вставлять строки, значения столбцов которых уже существуют в целевой таблице.

0 голосов
/ 24 апреля 2019
create table T_UNIQUE_VALUE( a number,b number, c varchar2(100));

alter table T_UNIQUE_VALUE ADD CONSTRAINT C_UNIQUE_VALUE UNIQUE (a,b);

Определить таблицу ошибок журнала. Оралс создаст err$_table_name

BEGIN 
   DBMS_ERRLOG.create_error_log(dml_table_name => 'T_UNIQUE_VALUE'); 
END;

Проверьте это.

execut 2 times  
insert into  T_UNIQUE_VALUE values(1,1,'a')  LOG ERRORS REJECT LIMIT UNLIMITED;

--check table T_UNIQUE_VALUE and  err$_T_UNIQUE_VALUE
select * from err$_T_UNIQUE_VALUE; -- 1 row 
select * from T_UNIQUE_VALUE;  -- 1 row

Изменить аннотацию пружины.

@Modifying
@Query(value = "insert into  T_UNIQUE_VALUE values(:a,:b,:c)  LOG ERRORS REJECT LIMIT UNLIMITED",  nativeQuery = true)
void insert_balbla(...)
0 голосов
/ 24 апреля 2019

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

Это было бы что-то вроде

@Query("SELECT r FROM Records r WHERE r.isNew = 1")
Collection<Record> findAllNewRecords();

А затем настройте считыватель как

RepositoryItemReader<Record> recordsReader = new RepositoryItemReader<>();
recordsReader.setRepository(recordsRepository);
recordsReader.setMethodName("findAllNewRecords");

Надеюсь, это поможет

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