Isso significa que você tem pelo menos uma linha na tabela que não pode ser convertida em
float
. Fazendo o CASE
é seguro, mas combinar o CTE e adicionar uma cláusula WHERE cai em uma falácia comum de programadores ao escrever T-SQL:essa ordem de declaração implica uma ordem de execução . Os programadores estão acostumados com o estilo procedural imperativo de linguagens como C e não conseguem compreender a natureza declarativa baseada em conjunto do SQL. Eu escrevi antes sobre esse problema e dei exemplos quando a falácia causa erros:- As funções T-SQL não implicam uma certa ordem de execução
- No operador booleano do SQL Server curto-circuito
Depois de postar seu código completo, podemos ver onde exatamente você cometeu a falácia no seu caso e assumiu uma certa ordem de execução.
após atualização
OK, então tenho que administrar que no seu caso o código está correto na ordem de execução, o
result
a coluna não pode ser projetada sem avaliar primeiro o CASE
. Se o CASE estivesse em uma cláusula WHERE, as coisas teriam sido diferentes. Seu problema é diferente:
ISNUMERIC
. Esta função tem uma compreensão muito generosa do que NUMERIC
significa e já mordeu muitos desenvolvedores antes. Ou seja, ele aceita valores que CAST e CONVERT irão rejeitar. Como aqueles que contêm uma vírgula:declare @n varchar(8000) = '1,000';
select isnumeric(@n);
select cast(@n as float);
select case when isnumeric(@n)=1 then cast(@n as float) else null end;
Então você tem valores que passam o
ISNUMERIC
teste, mas não converte. Apenas um aviso, quanto mais você se aprofundar nessa abordagem, mais portas fechadas você encontrará. Não é uma maneira segura de fazer o elenco que você precisa no lado do servidor. Idealmente, corrija o modelo de dados (torne o campo um float se ele armazenar floats). Fora isso, faça uma triagem dos dados e remova todos os valores que não são um float adequado e corrija o front-end/aplicativo para não introduzir mais novos e, em seguida, adicione uma restrição que acionará o erro se novos valores incorretos aparecerem. Você não poderá resolver isso em uma consulta, aquela estrada está cheia de corpos. Com a próxima versão do SQL Server você terá uma nova função,
TRY_CONVERT
, isso resolveria seu problema.