Estava eu depurando uma procedure no oracle e cheguei a conclusao que um dos sub-selects nao retornava nada e a partir dai a proc começava a perder o rumo das coisas. O select era algo bem simples:
Select campoA, campoB from Tabela where trim(campoC) = trim(parametro);
Como esse sistema veio de uma base legada temos varios campos cujo valor é ' ', ou seja, espaços em branco, por isso a proc precisa desse trim. O que estava acontecendo é que o select citado acima nao estava retornando valor nenhum. Verifiquei o valor do parametro passado e descobrir que era vazio ou ''. Lembre-se que vazio é diferente de nulo e diferente de zero. Como sabia que a tabela possui valores vazios no campo pesquisado, comecei a investigar. Eis os passos até a conclusão que decora o titulo desse post.
Primeiro eu rodei a seguinte query:
select 1 as result from dual --> retorna 1
select 1 as result from dual where trim('abc') = trim('abc')--> retorna 1
select 1 as result from dual where trim('abc') = trim('def')--> nao retorna nada
select 1 as result from dual where trim('') = trim('') --> nao retorna nada, ou seja, o where é falso
select 1 as result from dual where trim(' ') = trim(' ') --> nao retorna nada tambem, ou seja, o where é falso também. O que é estranho pois temos a mesma expressão dos dois lados do =.
Depois de pensar um pouco fiz o seguinte teste (depois de analisar algumas queries com length):
select 1 as result from dual where trim('') is null--> retorna 1
Aeeee entao descobri que o trim de vazio nao é vazio mas sim nulo! Entao o problema é quando o parametro passado é um valor vazio. Para valores nao vazios a query funciona mas quando quero comparar vazios, o select nao vai encontrar.
Para resolver esse problema acabei fazendo a query da seguinte forma, usando a funcao nvl:
select 1 as result from dual where nvl(trim(campo), ' ') = nvl(trim(parametro), ' ')
Explicacao: nvl é uma funcao que verifica se o primeiro parametro é nulo , se for a funcao retorna o segundo parametro. No meu caso eu verifico o trim do campo, se for nulo ele retorna um 1 espaco em branco. O mesmo é feito do outro lado do =, se ele vier vazio , o trim do vazio é nulo entao o nvl substitui por ' '. Se os dois forem espaco em branco, entao ' ' = ' ' , e o valor é retornado na query. Se os valores do campo e parametro forem diferentes de vazio, a query se comporta da mesma como se não tivesse o nvl.
Eis minha dica de hoje, que pode poupar algumas horas de debug na sua query. Talvez possa até haver uma maneira melhor de resolver esse problema, se houver , postem um comentário.
Have fun!
No comments:
Post a Comment