Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

erro ao converter varchar para float


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:

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.