1
I have a very large database that I have to copy information from. To decrease the use of memory I thought of inserting the information in parts, using a CURSOR
and paging the data, thus carrying out the insertion.
But to do that I would need one COMMIT
after insertion, that would still be within the CURSOR
. How can I do this? Is there any way to decrease the memory cost of this operation without needing this solution?
Edit:
The table I have is LOG
moving with a BLOB
with the message (which is a XML
compressed). The structure is similar to the following:
identificador INTEGER -- Agrupador
identificador_log INTEGER -- Identificador único (Não segue uma sequência)
processamento DATETIME -- A data em que o log foi gravado
mensagem BLOB -- XML comprimido com todas as informações da mensagem
The solution close to what I wish I arrived at was the following:
DECLARE
dias INTEGER;
indice INTEGER;
BEGIN
-- Diferença de dias entre as datas de logs
SELECT TRUNC(MAX(l.processamento)) - TRUNC(MIN(l.processamento)) INTO dias
FROM LOG l
ORDER BY l.processamento;
FOR indice IN REVERSE 1 .. dias LOOP
INSERT INTO TEMP_LOG(
identificador,
identificador_log,
processamento,
mensagem
)
SELECT tl.identificador,
tl.identificador_log,
tl.processamento,
l.mensagem
FROM (
SELECT l.identificador,
MAX(l.processamento) AS processamento,
MAX(l.identificador_log) KEEP (DENSE_RANK FIRST ORDER BY l.processamento DESC) AS identificador_log
FROM LOG l
GROUP BY l.identificador
) tl
INNER JOIN LOG l
ON tl.identificador = l.identificador
AND tl.identificador_log = l.identificador_log
AND tl.processamento = l.processamento
WHERE TRUNC(l.processamento) = TRUNC(sysdate - indice);
COMMIT;
END LOOP;
END;
/
The point is I have a lot of drives and a lot of files on BLOB
so I can’t make this copy at once, otherwise the memory usage will be exorbitant and it’s this problem that I want to solve: Make the copy without consuming resources so that you can activate some usage alert.
you can peacefully use a
commit
inside a cursor, as long as it is not in the table used by the cursor, which is not your case, but your biggest problem is performance, right? you can use abulk collect
to improve performance, have tried this idea?– Ricardo Pontual
@Ricardopunctual I didn’t try. Can you shed some light on that?
– Sorack
yes, it would be something like this:
OPEN seu_cursor;
 LOOP
 FETCH seu_cursor
 BULK COLLECT INTO table_para_inserir


 END LOOP;
, where the fields the cursor must be the same as the "table_para_insert", or your type– Ricardo Pontual
if you have more data we can make a more functional example, but I believe that seeing this link will already understand the idea: oracle Bulk Collect
– Ricardo Pontual
@Ricardopontual added more information
– Sorack