Cela signifie que vous avez au moins une ligne dans la table qui ne peut pas être convertie en float
. Faire le CASE
est sûr, mais combiner le CTE et ajouter une clause WHERE tombe dans une erreur courante des programmeurs lors de l'écriture de T-SQL :cet ordre de déclaration implique un ordre d'exécution . Les programmeurs sont habitués au style procédural impératif des langages de type C et ne comprennent pas la nature déclarative basée sur les ensembles de SQL. J'ai déjà écrit sur ce problème et donné des exemples où l'erreur provoque des erreurs :
- Les fonctions T-SQL n'impliquent pas un certain ordre d'exécution
- Sur l'opérateur booléen SQL Server court-circuit
Une fois que vous avez posté votre code complet, nous pouvons voir exactement où vous avez commis l'erreur dans votre cas et supposé un certain ordre d'exécution.
après mise à jour
OK, je dois donc administrer que dans votre cas le code est correct dans l'ordre d'exécution, le result
la colonne ne peut pas être projetée sans d'abord évaluer le CASE
. Si le CASE avait été dans une clause WHERE, les choses auraient été différentes.
Votre problème est différent :ISNUMERIC
. Cette fonction a une compréhension très généreuse de ce que NUMERIC
signifie et a mordu de nombreux développeurs avant. A savoir, il accepte les valeurs que CAST et CONVERT rejetteront. Comme celles contenant une virgule :
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;
Vous avez donc des valeurs qui passent le ISNUMERIC
test mais ne parvient pas à convertir. Juste un avertissement, plus vous approfondirez cette approche, plus vous trouverez de portes fermées. Il n'y a tout simplement pas de moyen sûr de faire le casting dont vous avez besoin côté serveur. Idéalement, corrigez le modèle de données (faites du champ un flottant s'il stocke des flottants). En dehors de cela, triez les données et supprimez toutes les valeurs qui ne sont pas un flotteur approprié, et corrigez le front-end/application pour ne plus en introduire de nouvelles, puis ajoutez une contrainte qui déclenchera l'erreur si de nouvelles mauvaises valeurs apparaissent. Vous ne pourrez pas résoudre cela dans une requête, cette route est jonchée de corps.
Avec la prochaine version de SQL Server, vous aurez une nouvelle fonction, TRY_CONVERT
, cela résoudrait votre problème.