Det betyder att du har minst en rad i tabellen som inte kan kastas till float
. Gör CASE
är säkert, men att kombinera CTE och lägga till en WHERE-sats faller in i ett vanligt misstag för programmerare när de skriver T-SQL:den deklarationsordningen innebär en exekveringsordning . Programmerare är vana vid den imperativa procedurstilen för C-liknande språk och misslyckas med att förstå den deklarativa uppsättningsbaserade naturen hos SQL. Jag har skrivit tidigare om det här problemet och gett exempel när felet orsakar fel:
När du har lagt upp din fullständiga kod kan vi se exakt var du gjorde felet i ditt fall och antog en viss utförandeordning.
efter uppdatering
OK, så jag måste administrera att i ditt fall är koden korrekt i körningsordningen, result
kolumnen kan inte projiceras utan att först utvärdera CASE
. Hade CASE varit i en WHERE-klausul hade saker och ting varit annorlunda.
Ditt problem är annorlunda:ISNUMERIC
. Denna funktion har en mycket generös förståelse för vad NUMERIC
betyder och har bitit många utvecklare tidigare. Den accepterar nämligen värden som CAST och CONVERT kommer att avvisa. Som de som innehåller ett kommatecken:
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;
Så du har värden som passerar ISNUMERIC
testa men misslyckas med att konvertera. Bara ett meddelande, ju mer du gräver i det här tillvägagångssättet, desto fler stängda dörrar hittar du. Är helt enkelt inget säkert sätt att göra casten du behöver på serversidan. Helst fixar du datamodellen (gör fältet till ett flytande om det lagrar flytningar). Kort om det, triage data och ta bort alla värden som inte är ett korrekt flytande, och fixa gränssnittet/applikationen för att inte längre introducera nya, lägg sedan till en begränsning som kommer att utlösa felet om nya dåliga värden dyker upp. Du kommer inte att kunna lösa detta i en fråga, den vägen är full av kroppar.
Med nästa version av SQL Server kommer du att ha en ny funktion, TRY_CONVERT
, det skulle lösa ditt problem.