sexta-feira, fevereiro 23, 2007

Cast dentro do where em SQL

Este problema foi descoberto por um colega meu (obrigado Sérgio), mas como achei interessante vou aproveitar o mail que ele me enviou para explicar o problema.


Ao fazer um SELECT em que seja usado um CAST no WHERE, separar em dois selects: um primeiro que faz todas as outras validações e guarda o resultado numa variável do tipo tabela, e outro que pega nesses resultados e aplica a condição com o CAST. Ou seja, em vez de:
SELECT A.ID, A.Tipo, A.Valor
FROM A
WHERE A.Tipo = 'TipoDeValorSeguroParaFazerCast'
AND CAST(A.Valor AS FLOAT) > 0
passar a:
DECLARE @TABELA_TEMP table (ID bigint, Tipo varchar(30), Valor varchar(50));
INSERT INTO @TABELA_TEMP

SELECT A.ID, A.Tipo, A.Valor
FROM A
WHERE A.Tipo = 'TipoDeValorSeguroParaFazerCast'
SELECT ID, Tipo, Valor
FROM @TABELA_TEMP
WHERE CAST(A.Valor AS FLOAT) > 0

Assim evitam-se erros obscuros de CAST em algumas situações, em que se fazia CAST a tudo, inclusive entradas que não obedeciam a 'TipoDeValorSeguroParaFazerCast'... Claro que isto não é assim tão simples, e provavelmente só acontece em combinações específicas de índices e joins entre tabelas, etc., mas como regra geral é preferível prevenir.

Sem comentários: