GPO ( Grupo de Profissionais Oracle )
A maior comunidade Oracle do Brasil !

Inserindo em uma tabela utilizando FORALL

Boa tarde !

Preciso alimentar uma tabela com dados que leio através de um SQL. Tentei usar insert normal mas ficou muito lento !

Verifiquei na internet e vi que o pessoal usa BULK COLLECTION mas não consegui montar algo funcional. Você pode me ajudar com alguma dica ?

Toledo


Toledo, como conversado anteriormente, irei demonstrar como podemos resolver esse seu problema utilizando FORALL.O objetivo desse post não é discutir sobre sua performance, e sim sobre como o  implementar em  seu código.

Primeiramente, vamos criar as nossas tabelas para o nosso teste e inserir alguns dados: 

CREATE TABLE teste
(
 codigo    NUMBER,
 descricao VARCHAR2(2000)
)
/

INSERT INTO teste (codigo,descricao) VALUES (1,'DESCRICAO 1');
INSERT INTO teste (codigo,descricao) VALUES (2,'DESCRICAO 2');
INSERT INTO teste (codigo,descricao) VALUES (3,'DESCRICAO 3');
INSERT INTO teste (codigo,descricao) VALUES (4,'DESCRICAO 4');
INSERT INTO teste (codigo,descricao) VALUES (5,'DESCRICAO 5');
INSERT INTO teste (codigo,descricao) VALUES (6,'DESCRICAO 6');
INSERT INTO teste (codigo,descricao) VALUES (7,'DESCRICAO 7');
INSERT INTO teste (codigo,descricao) VALUES (8,'DESCRICAO 8');
INSERT INTO teste (codigo,descricao) VALUES (9,'DESCRICAO 9');
INSERT INTO teste (codigo,descricao) VALUES (10,'DESCRICAO 10');
INSERT INTO teste (codigo,descricao) VALUES (1,'DESCRICAO 1');
INSERT INTO teste (codigo,descricao) VALUES (2,'DESCRICAO 2');
INSERT INTO teste (codigo,descricao) VALUES (3,'DESCRICAO 3');
INSERT INTO teste (codigo,descricao) VALUES (4,'DESCRICAO 4');
INSERT INTO teste (codigo,descricao) VALUES (5,'DESCRICAO 5');
INSERT INTO teste (codigo,descricao) VALUES (6,'DESCRICAO 6');
INSERT INTO teste (codigo,descricao) VALUES (7,'DESCRICAO 7');
INSERT INTO teste (codigo,descricao) VALUES (8,'DESCRICAO 8');
INSERT INTO teste (codigo,descricao) VALUES (9,'DESCRICAO 9');
INSERT INTO teste (codigo,descricao) VALUES (10,'DESCRICAO 10');

CREATE TABLE teste2
(
 codigo    NUMBER,
 descricao VARCHAR2(2000)
)
/

Pronto, agora vamos ao nosso código:

DECLARE
  -- Variable

 TYPE v_tabData IS TABLE OF teste%ROWTYPE; 
  v_tabBulk v_tabData;
  x NUMBER := 0

  CURSOR c1 IS
  SELECT a.codigo
  ,a.descricao
  FROM teste a;

BEGIN
  -- Trunca a tabela
  DBMS_OUTPUT.put_line('Truncando a tabela...');
  DBMS_UTILITY.exec_ddl_statement('TRUNCATE TABLE teste2');

  OPEN c1;
  LOOP
  DBMS_OUTPUT.put_line('Iniciando leitura...'); 

  -- Fetch Collection
  FETCH c1 BULK COLLECT INTO v_tabBulk;

  DBMS_OUTPUT.put_line('Registro(s) a serem processados: ' || v_tabBulk.COUNT );

 -- Verifica se há registros
  IF v_tabBulk.COUNT > 0 
  THEN
  FORALL x IN 1..v_tabBulk.COUNT
  INSERT INTO teste2
  VALUES v_tabBulk(x);
  DBMS_OUTPUT.put_line('Registros processados...');

 END IF;

 EXIT WHEN c1%NOTFOUND;
  COMMIT;

 END LOOP;

 -- Não esqueça de fechar o seu cursor :)

 CLOSE c1;

 DBMS_OUTPUT.put_line('Fim do processo...');

EXCEPTION
  WHEN others THEN
  DBMS_OUTPUT.put_line('[ ERRO ] ' || DBMS_UTILITY.format_error_stack);

  IF SQL%ISOPEN
  THEN 
  -- Não esqueça de fechar o seu cursor :)
  CLOSE c1;

  END IF;

END;

Como a estrutura da tabela é idêntica ao do resultado do SELECT, pude utilizar o ROWTYPE da tabela como record do meu TYPE do tipo TABLE. O que facilita em muito o trabalho. Observe que estou lendo todos os dados da TABELA 1 e salvando na TABELA2.

Pronto Toledo, agora é só adaptar a suas necessidades. Espero que seja de grande ajuda a você e ao pessoal que acompanha o blog.

Um grande abraço

Share

You may also like...

2 Responses

  1. Notria disse:

    Olá Sérgio, boa tarde!
    Muito boa dica, parabéns!
    Preciso de um help. No caso do cursor ser referente a tabelas relacionadas como fazer? É a mesma lógica?

Deixe um comentário

O seu endereço de e-mail não será publicado.