Problemas ao trafegar Number ou Date como caracter

22, Setembro 2008

Um problema muito comum ao trafegar Number ou Date como caracter refere-se à formatação dos valores. Toda conexão com o banco de dados Oracle cria algumas váriáveis de sessão, que podem variar de uma sessão para outra causando assim erros que podem parecer intermitentes, por exemplo, funciona no Desenvolvimento e não na Homologação ou funciona na máquina de um usuário e na de outro dá problema.
Para evitar esses transtornos, o ideal é forçar o valor a ser atribuído para o formato esperado.

Ex:

declare
   numero        number(10,2);
   numberoAux varchar2(6) := '1,00';
   data           date;
   dataAux      varchar2(12) := '10/01/2008';
begin
   -- Errado
   numero := numberoAux; -- Dependendo do formato de pontuação da sessão, poderá disparar uma exception
   -- Certo
   numero := to_number(numberoAux,'999g999g999g990d00','nls_numeric_characters='',.''');

   -- Errado
   data := dataAux; -- Dependendo do formato de data da sessão, poderá disparar uma exception
   -- Certo
   data := to_date(dataAux,'dd/mm/rrrr');
end;

Quando usar o %type e %rowtype

25, Julho 2008

Um problema muito comum ao definirmos uma precisão fixa em uma variável é a possibilidade de que a precisão de uma coluna em uma tabela seja alterada, por exemplo, existe uma tabela de clientes declarada assim:

   codigo number(4);
   nome varchar2(30);

Para receber esses valores em um bloco PL/SQL foram criadas as variáveis:

   v_codigo number(4);
   v_nome  varchar2(30);

Essas variáveis receberão os valores da tabela num dado momento. Porém, se houver a necessidade de aumentar a precisão da coluna codigo na tabela de 4 para 5 posições, isso ocasionará um erro de precisão ao tentar atribuir os valores. A não ser que a variável do seu bloco PL/SQL seja alterado para a nova precisão de 5 posições. Percebem que foi criada uma dependência de alteração do seu programa sempre que uma coluna for alterada. Para resolver esse problema, utilizamos o atributo %type. Esse atributo elimina a necessidade de alterar seu programa sempre que uma coluna for alterada, ele sempre terá o mesmo tipo de uma coluna da tabela. Exemplo:

  declare
      v_codigo clientes.codigo%type;
      v_nome clientes.nome%type;
  begin
      select codigo, nome
         into v_codigo, v_nome
        from clientes
      where codigo = 10;
  end;

Com o %type ficamos isentos de alterar a precisão de uma coluna, porém, caso uma nova coluna seja criada na tabela, precisaremos criar uma nova variável para receber esse valor. Neste caso podemos utilizar o atributo %rowtype. Com este atributo, teremos uma variável com exatamentoea mesma estrutura de uma tabela ou de um cursor. Veja o Exemplo:

   declare
       rec_clientes clientes%rowtype;
   begin
       select *
          into rec_clientes
         from clientes
       where cd_cliente = 10;

       /*
        Para utilizar uma variável do tipo %rowtype,
        basta colocar <variável>.<coluna>. Veja abaixo:
      */

      dbms_output.put_line('Codigo: '||rec_clientes.cd_cliente||chr(10)||
                            'Nome:  '||rec_clientes.nm_cliente);
   end;

that´s all folks