O que é a cláusula NOCOPY?
Por padrão, quando passamos parâmetros para procedimentos e funções em PL/SQL, eles são passados por valor, significando que uma cópia local é criada no bloco PL/SQL chamado. Para grandes estruturas de dados, isso pode ser ineficiente em termos de tempo e memória. A cláusula NOCOPY
sugere ao compilador que ele deve passar os parâmetros por referência, em vez de por valor.
Vantagens detalhadas da cláusula NOCOPY
- Desempenho Aprimorado: Como mencionado anteriormente, ao evitar a cópia de grandes estruturas de dados, você economiza em tempo e memória. Isso é especialmente notável quando trabalhamos com grandes coleções ou tipos de registros.
- Mudanças Imediatas: Ao trabalhar com parâmetros
IN OUT
, as mudanças feitas ao parâmetro dentro da subrotina são refletidas imediatamente no argumento original, sem precisar de um retorno explícito. - Utilização em Tipos Complexos: Especialmente útil ao trabalhar com registros, tabelas indexadas e outros tipos avançados. Ajuda a evitar processos tediosos de desempacotamento e reempacotamento de dados.
Exemplos Práticos
Uso Básico com Variáveis Simples
DECLARE
v_num NUMBER := 5;
PROCEDURE double_value(p_value IN OUT NOCOPY NUMBER) IS
BEGIN
p_value := p_value * 2;
END double_value;
BEGIN
double_value(v_num);
DBMS_OUTPUT.PUT_LINE(v_num); -- Outputs: 10
END;
Uso com Registros
Vamos supor que temos um tipo de registro que representa uma pessoa:
DECLARE
TYPE t_person IS RECORD(
first_name VARCHAR2(50),
last_name VARCHAR2(50),
age NUMBER
);
v_person t_person := t_person('John', 'Doe', 30);
PROCEDURE update_person(p_person IN OUT NOCOPY t_person) IS
BEGIN
p_person.age := p_person.age + 1;
END update_person;
BEGIN
update_person(v_person);
DBMS_OUTPUT.PUT_LINE(v_person.age); -- Outputs: 31
END;
Uso com Tabelas Indexadas
DECLARE
TYPE t_numbers IS TABLE OF NUMBER INDEX BY PLS_INTEGER;
v_nums t_numbers;
PROCEDURE populate_nums(p_nums IN OUT NOCOPY t_numbers) IS
BEGIN
FOR i IN 1..10 LOOP
p_nums(i) := i * 2;
END LOOP;
END populate_nums;
BEGIN
populate_nums(v_nums);
DBMS_OUTPUT.PUT_LINE(v_nums(5)); -- Outputs: 10
END;
Conclusão
A cláusula NOCOPY
oferece uma maneira eficiente de trabalhar com parâmetros em PL/SQL, especialmente quando se trata de estruturas de dados mais complexas. No entanto, deve-se ter cuidado ao usá-la, garantindo que o comportamento por referência seja realmente o desejado na situação em questão.
Abs
Referências
- Oracle Database PL/SQL Language Reference
- Steven Feuerstein “Oracle PL/SQL Programming”