Я создал рабочий процесс весенней интеграции, который загружает данные из csv в базу данных oracle. Это кластерная среда, в которой каждый узел обрабатывает один CSV-файл и загружает данные во временную таблицу.
Структура временной таблицы: (индекс по AccountNumber
)
ID
AccountNumber
ItemId
Value
У меня есть конфигурация rabbitmq для весенней интеграции, которая публикует имена файлов в очереди. Каждый узел в кластере выбирает только один файл, читает csv из файловой системы (общая файловая система и база данных Oracle) и загружает данные в таблицу TEMP. (Размер каждого CSV составляет 2 ГБ).
После загрузки всех данных во временную таблицу один узел должен переместить данные из временной таблицы в основную таблицу, которая имеет ту же структуру, что и временная таблица.
Основная таблица: (индекс по Account Number
)
Id
AccountNumber
ItemId
Value
Я создал хранимую процедуру, которая удаляет существующие номера учетных записей из основной таблицы и загружает учетные записи в основной таблице.
После перемещения данных в основную таблицу я удаляю данные из временной таблицы в конце процедуры.
Мой вопрос заключается в том, какой оптимальный способ обрезать эту таблицу.
Проблема: предположим, у меня есть эта запись в моей основной таблице.
Основной стол:
Account Number ItemId ItemValue
-----------------------------------
123456 5 XYZ
123456 6 ABC
123456 7 DEF
Теперь я получаю эту запись из таблицы csv во временную таблицу:
AccountNumber ItemId ItemValue
------------------------------------
123456 5 FGH
теперь моя главная таблица должна иметь только одно значение. Строки с ItemId 6 и 7 должны быть удалены.
Account Number ItemId ItemValue
-------------------------------------
123456 5 FGH
Могу ли я достичь этого слиянием с?
Сценарий 1 :
Было бы лучше обрезать эту таблицу перед загрузкой данных в таблицу TEMP? (Две отдельные транзакции базы данных, одна для усеченной таблицы и другая для перемещения данных).
(вызывается перед публикацией имен файлов в очереди)
одна процедура для очистки временной таблицы партиями перед загрузкой.
Шаг 1:
create or replace procedure CleanTempTable
IS
v_numberRows int :=20000;
BEGIN
loop
Delete from TEMP where rownum <= v_numberRows;
EXIT WHEN SQL%ROWCOUNT = 0;
commit;
END LOOP;
END;
/
Одна процедура для перемещения данных из временной в главную.
Это вызывает в конце на этапе консолидации.
CREATE OR REPLACE PROCEDURE LOAD_DATA_TO_CONSOLIDATE (updatecount OUT NUMBER )
IS
cnt number := 0;
account_num MAIN_TABLE.ACCOUNT_NO%TYPE;
CURSOR account_cursor IS
SELECT distinct ACCOUNT_NO from TEMP_TABLE;
BEGIN
OPEN account_cursor;
LOOP
FETCH account_cursor INTO account_num;
EXIT WHEN account_cursor%NOTFOUND;
delete from MAIN where ACCOUNT_NO = account_num;
insert into MAIN(ID,ACCOUNT_NO,FACT_ID,FACT_VALUE) select HIBERNATE_SEQUENCE.nextval,temp.ACCOUNT_NO,temp.VALUE from TEMP temp
where ACCOUNT_NO = account_num;
cnt := cnt + sql%rowcount;
commit;
END LOOP;
updatecount := cnt;
CLOSE account_cursor;
END LOAD_DATA_TO_CONSOLIDATE;
Сценарий 2:
было бы лучше обрезать эту таблицу после перемещения данных из таблицы TEMP в основную таблицу (все внутри одной хранимой процедуры (в одной транзакции БД))
CREATE OR REPLACE PROCEDURE LOAD_DATA_TO_CONSOLIDATE (updatecount OUT NUMBER )
IS
cnt number := 0;
account_num MAIN_TABLE.ACCOUNT_NO%TYPE;
CURSOR account_cursor IS
SELECT distinct ACCOUNT_NO from TEMP_TABLE;
BEGIN
OPEN account_cursor;
LOOP
FETCH account_cursor INTO account_num;
EXIT WHEN account_cursor%NOTFOUND;
delete from MAIN where ACCOUNT_NO = account_num;
insert into MAIN(ID,ACCOUNT_NO,FACT_ID,FACT_VALUE) select HIBERNATE_SEQUENCE.nextval,temp.ACCOUNT_NO,temp.VALUE from TEMP temp
where ACCOUNT_NO = account_num;
cnt := cnt + sql%rowcount;
commit;
END LOOP;
updatecount := cnt;
CLOSE account_cursor;
delete from TEMP; //removing all data
END LOAD_DATA_TO_CONSOLIDATE;