Pular para o conteúdo

Variáveis em Packages: O perigo de declarações públicas em bancos de dados

Variáveis em Packages

Packages são uma ferramenta muito poderosa dentro do banco de dados. Podemos incluir diversas functions, procedures, tipos de dados, collections e etc, todas agrupadas e organizadas de acordo com a lógica do negócio. Facilitando muito assim o trabalho de todos.

As vezes, queremos compartilhar variáveis dentro dos componentes do packages, algo que é comum entre várias partes do mesmo. Ou queremos ter uma variável global, onde todos podem ter o acesso. Mas é aí que existe um perigo. Pois, se uma variável for declarada no package, ela será visível a todos, eserá pública, sendo assim, alguém poderá modificá-la, resultado em erros posteriores. Vejamos como isso pode ocorrer.

CREATE OR REPLACE PACKAGE teste AS 
  pv_teste NUMBER := 1;
END teste;

No exemplo acima, podemos ver um package extremamente simples, que contem apenas uma variável pública, que é visível para todos que tenham acesso ao package. Agora imagem que uma função ou procedure dependa dessa variável e que alguém faça exatamente o que nos mostra o exemplo a seguir.

BEGIN
  teste.pv_teste := 2;
  dbms_output.put_line(teste.pv_teste);
END;

O valor a ser impresso será 2 e não 1. Declarar variáveis dentro do package é uma prática que deverá ser evitada. Caso seja necessário fazer isso, para que vários usuários tenham acesso a essa variável, ela deverá ser declarada como CONSTANT. Veja a seguir como ficaria.

CREATE OR REPLACE PACKAGE teste AS 
  pv_teste CONSTANT NUMBER := 1;
END teste;

BEGIN
  teste.pv_teste := 2;
  dbms_output.put_line(teste.pv_teste);
END;

Assim, ao tentar alterar o conteúdo da variável um erro seria lançado. Isso protege o valor da variável. Caso não seja necessário que ninguém acesse essa variável de modo direto, mas sim que exista uma variável compartilhada somente para o funcionamento interno dos componentes do package, como procedures e functions, devemos evitar declarar essa variável no package. Ao invés disso ela deverá ser declarada do corpo package. Vejamos como ficaria.

CREATE OR REPLACE PACKAGE teste AS 
  pv_var1 NUMBER := 1;
  PROCEDURE pf_teste;
END teste;

CREATE OR REPLACE PACKAGE BODY teste AS 
  pv_var2 NUMBER := 1;  
  PROCEDURE pf_teste IS
    BEGIN
      dbms_output.put_line(pv_var2);
    END;
END teste;

BEGIN
  teste.pv_var1 := 2;
  dbms_output.put_line('pv_var1: '||teste.pv_var1);
  teste.pv_var2 := 2;
  dbms_output.put_line('pv_var1: '||teste.pv_var2);  
END;

Assim, dessa forma, o conteúdo da variável pv_var1 será modificado, mas ao tentar modificar o da variável pv_var2 será lançado um erro, como se não existisse essa variável. Sendo assim a variável pv_var2 é privada. Caso seja necessário acessar o conteúdo dela, existe a procedure teste.pf_teste que retorna o valor da variável para exibição no console. Dessa mesma maneira, poderíamos criar uma procedure para modificar a variável pv_var2. Isso é algo bem comum e conhecido em outras linguagens de programação como JAVA por exemplo. Onde as variáveis são privadas e é criado métodos getters e setters para acesso e modificação da variável. Então, tomem cuidado ao utilizar variáveis em packages, estejam atentos ao que foi discutido aqui.

Referência

Abraço

Quão útil foi este post ?

Clique em uma estrela para classificar o post

nota média 5 / 5. Contagem de votos: 30

Sem votos ! Seja o primeiro a classificar !

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

plugins premium WordPress