Oracle PL/SQL BULK COLLECT: Exemplo FORALL
โก Resumo Inteligente
COLETA EM GRANDE QUANTIDADE em Oracle PL/SQL busca vรกrias linhas de uma sรณ vez em uma coleรงรฃo, enquanto FORALL envia operaรงรตes DML em massa de volta para o banco de dados. Ambos reduzem as trocas de contexto entre os mecanismos SQL e PL/SQL, aumentando o desempenho.

O que รฉ COLETA EM GRANEL?
A COLETA EM MASSA reduz as trocas de contexto entre os SQL e o mecanismo PL/SQL, permitindo que o mecanismo SQL busque os registros de uma sรณ vez.
Oracle PL/SQL Oferece a funcionalidade de buscar registros em lote, em vez de buscรก-los um por um. Este comando BULK COLLECT pode ser usado em uma instruรงรฃo SELECT para preencher os registros em lote ou para buscar um conjunto de registros. cursor Em lote. Como o BULK COLLECT busca os registros em lote, a clรกusula INTO deve sempre conter uma variรกvel de tipo de coleรงรฃo. A principal vantagem de usar o BULK COLLECT รฉ o aumento de desempenho, que reduz a interaรงรฃo entre o banco de dados e o mecanismo PL/SQL.
Sintaxe:
SELECT <column1> BULK COLLECT INTO bulk_variable FROM <table name>; FETCH <cursor_name> BULK COLLECT INTO <bulk_variable>;
Na sintaxe acima, BULK COLLECT รฉ usado para coletar os dados das instruรงรตes SELECT e FETCH.
Clรกusula FORALL
A instruรงรฃo FORALL executa Operaรงรตes DML em dados em massa. Assemelha-se a uma instruรงรฃo de laรงo FOR, exceto que em um laรงo FOR as aรงรตes ocorrem no nรญvel do registro, enquanto em FORALL nรฃo existe o conceito de laรงo. Em vez disso, todos os dados presentes no intervalo especificado sรฃo processados โโsimultaneamente.
Sintaxe:
FORALL <loop_variable> in <lower range> .. <higher range>
<DML operations>;
Na sintaxe acima, a operaรงรฃo DML fornecida serรก executada para todos os dados presentes entre os limites inferior e superior.
Clรกusula LIMIT
O conceito de coleta em massa carrega todos os dados na variรกvel de coleรงรฃo de destino de uma sรณ vez, ou seja, todos os dados serรฃo inseridos na variรกvel de coleรงรฃo de uma sรณ vez. No entanto, isso nรฃo รฉ recomendรกvel quando o nรบmero total de registros a serem carregados รฉ muito grande, pois, ao tentar carregar todos os dados, o PL/SQL consome mais memรณria da sessรฃo. Portanto, รฉ sempre bom limitar o tamanho dessa operaรงรฃo de coleta em massa.
Esse limite de tamanho pode ser facilmente alcanรงado introduzindo a condiรงรฃo ROWNUM na instruรงรฃo SELECT, enquanto que no caso de um cursor isso nรฃo รฉ possรญvel.
Para superar isso, Oracle forneceu a clรกusula LIMIT que define o nรบmero de registros que precisam ser incluรญdos no lote.
Sintaxe:
FETCH <cursor_name> BULK COLLECT INTO <bulk_variable> LIMIT <size>;
Na sintaxe acima, a instruรงรฃo de busca do cursor usa a instruรงรฃo BULK COLLECT juntamente com a clรกusula LIMIT.
BULK COLLECT Atributos
Semelhante aos atributos de cursor, o comando BULK COLLECT possui a funรงรฃo %BULK_ROWCOUNT(n), que retorna o nรบmero de linhas afetadas na n-รฉsima instruรงรฃo DML do comando FORALL, ou seja, fornece a contagem de registros afetados na instruรงรฃo FORALL para cada valor da variรกvel de coleรงรฃo. O termo 'n' indica a sequรชncia do valor na coleรงรฃo para a qual a contagem de linhas รฉ necessรกria.
1 exemplo: Neste exemplo, vamos projetar todos os nomes dos funcionรกrios da tabela `emp` usando BULK COLLECT e tambรฉm vamos aumentar o salรกrio de todos os funcionรกrios em 5000 usando FORALL.
A captura de tela abaixo mostra este exemplo de BULK COLLECT e FORALL juntamente com sua saรญda em Oracle.
DECLARE CURSOR guru99_det IS SELECT emp_name FROM emp; TYPE lv_emp_name_tbl IS TABLE OF VARCHAR2(50); lv_emp_name lv_emp_name_tbl; BEGIN OPEN guru99_det; FETCH guru99_det BULK COLLECT INTO lv_emp_name LIMIT 5000; FOR c_emp_name IN lv_emp_name.FIRST .. lv_emp_name.LAST LOOP Dbms_output.put_line('Employee Fetched:'||c_emp_name); END LOOP; FORALL i IN lv_emp_name.FIRST .. lv_emp_name.LAST UPDATE emp SET salary=salary+5000 WHERE emp_name=lv_emp_name(i); COMMIT; Dbms_output.put_line('Salary Updated'); CLOSE guru99_det; END; /
saรญda
Employee Fetched:BBB Employee Fetched:XXX Employee Fetched:YYY Salary Updated
Code Explicaรงรฃo:
- Code linha 2: Declarando o cursor guru99_det para a instruรงรฃo 'SELECT emp_name FROM emp'.
- Code linha 3: Declarando lv_emp_name_tbl como um tipo de tabela VARCHAR2(50).
- Code linha 4: Declarando lv_emp_name como o tipo lv_emp_name_tbl.
- Code linha 6: Abrindo o cursor.
- Code linha 7: Obtendo o cursor usando BULK COLLECT com o tamanho LIMIT definido como 5000 e armazenando-o na variรกvel lv_emp_name.
- Code linhas 8-11: Configure um loop FOR para imprimir todos os registros da coleรงรฃo lv_emp_name.
- Code linha 12: Utilizando a funรงรฃo FORALL para atualizar o salรกrio de todos os funcionรกrios em 5000.
- Code linha 14: Comprometer-se com o transaรงรฃo.

