Това означава, че имате поне един ред в таблицата, който не може да бъде прехвърлен към float
. Извършване на CASE
е безопасно, но комбинирането на CTE и добавянето на клауза WHERE попада в често срещана грешка на програмистите, когато пишат T-SQL:че редът на деклариране предполага ред на изпълнение . Програмистите са свикнали с императивния процедурен стил на езиците, подобни на C, и не успяват да разберат декларативния набор, базиран на природата на SQL. Писал съм преди за този проблем и дадох примери, когато грешката причинява грешки:
- T-SQL функциите не предполагат определен ред на изпълнение
- В булевия оператор на SQL Server късо съединение
След като публикувате пълния си код, можем да видим къде точно сте направили грешката във вашия случай и сме приели определен ред на изпълнение.
след актуализация
Добре, така че трябва да админирам, че във вашия случай кодът е правилен в реда на изпълнение, result
колоната не може да бъде проектирана без първо да се оцени CASE
. Ако CASE беше в клауза WHERE нещата щяха да са различни.
Вашият проблем е различен:ISNUMERIC
. Тази функция има много щедро разбиране за това какво NUMERIC
означава и е ухапал много разработчици преди. А именно, той приема стойности, които CAST и CONVERT ще отхвърлят. Като такива, съдържащи запетая:
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;
Така че имате стойности, които преминават ISNUMERIC
тест, но не успява да конвертира. Внимание, колкото повече се задълбочавате в този подход, толкова повече затворени врати ще откриете. Просто не е безопасен начин да направите кастинга, от който се нуждаете, от страната на сървъра. В идеалния случай коригирайте модела на данните (направете полето плаващо, ако съхранява плаващи стойности). Като изключим това, сортирайте данните и премахнете всички стойности, които не са правилни плаващи стойности, и коригирайте предния край/приложението, така че вече да не въвежда нови, след което добавете ограничение, което ще задейства грешката, ако се появят нови лоши стойности. Няма да можете да разрешите това чрез заявка, този път е осеян с тела.
Със следващата версия на SQL Server ще имате нова функция, TRY_CONVERT
, това ще реши проблема ви.