2012-02-28 2 views
2
CASE 
WHEN (Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)- FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)))> 0 AND (Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)- FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)))<=0.25 THEN (0.25+FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar))) 

WHEN (Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)- FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)))> 0.25 AND (Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)- FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)))<=0.50 THEN (0.50+FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar))) 

WHEN (Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)- FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)))> 0.50 AND (Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)- FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)))<=0.75 THEN (0.75+FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar))) 

WHEN (Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)- FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)))> 0.75 AND (Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)- FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)))<1 THEN (1+FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar))) 


WHEN (Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)- FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)))= 0 THEN (0+FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar))) 

END 

AS Estimated_Effort_Days, 

Приведенный выше код в настоящее время округляет поле под названием totaleffort до ближайшего.25, например, если у меня есть значение 78.19, оно будет округлено до 78.25.Ошибка преобразования типа данных varchar в float

У меня есть новое требование для значения нуля, когда значение = 0, тогда мне нужно отобразить текст «неизвестный номер». Я попытался добавить дополнительный оператор case, однако запрос не запускается с ошибкой:

Error converting data type varchar to float.

кто-нибудь есть для меня рекомендованы кем

ответ

1

Прежде всего, ваш настоящий код возвращает номер. И вы пытаетесь добавить условие, когда оно должно вернуть строку . Проблема заключается в том, что числовые типы имеют приоритет над типами строк, и поэтому в результате SQL Server попытается преобразовать ваше строковое сообщение в число (и сбой).

Чтобы избежать этого, вы должны убедиться, что все числовые значения, которые вы возвращаете, правильно преобразуются в строки, , а затем, вы можете легко добавить любое требуемое сообщение в качестве замены нулей.

Другое дело, ваша техника округления кажется мне сложной. Если вы хотите округлить, просто используйте CEILING(). Если вы хотите, чтобы округлить до ближайшего 0.25, вы можете умножить на 4, применяются CEILING(), а затем разделить на 4.

Вот моя попытка иллюстрирующей то, что я имею в виду:

WITH data (totaleffort) AS (
    SELECT CAST(123.5 AS float) UNION ALL 
    SELECT 88 UNION ALL 
    SELECT 0.067 UNION ALL 
    SELECT 0 UNION ALL 
    SELECT 9608.14 
) 
SELECT 
    ISNULL(
    CAST(CAST(NULLIF(CEILING(totaleffort * 4/7.40)/4, 0) AS decimal(10, 2)) AS nvarchar(30)), 
    'unknown number' 
) 
FROM data 

Выход:

------------------------------ 
16.75 
12.00 
0.25 
unknown number 
1298.50 

Вы также можете увидеть, что я использую ISNULL() и NULLIF() здесь, чтобы заменить 0 с помощью специального текста. Вот как это работает:

  • результат вычисления передается NULLIF, чей второй аргумент 0 - это означает, что если результат 0, NULLIF вернется NULL, в противном случае она возвращает результат;

  • сейчас ISNULL делает обратное: он возвращает второй аргумент, если первый имеет значение NULL, в противном случае он возвращает первый аргумент.

Итак, с этой цепочкой преобразований нуль эффективно становится 'unknown number'.

1

Предполагая, что вы хотите добавить, когда значение вашего состояния 0, они делают это так:

CASE 

WHEN (Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)- FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)))=0 THEN 
"unknown number" 


WHEN (Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)- FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)))> 0 AND (Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)- FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)))<=0.25 THEN (0.25+FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar))) 

WHEN (Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)- FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)))> 0.25 AND (Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)- FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)))<=0.50 THEN (0.50+FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar))) 

WHEN (Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)- FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)))> 0.50 AND (Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)- FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)))<=0.75 THEN (0.75+FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar))) 

WHEN (Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)- FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)))> 0.75 AND (Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)- FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)))<1 THEN (1+FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar))) 


WHEN (Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)- FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)))= 0 THEN (0+FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar))) 

END 

AS Estimated_Effort_Days, 
+0

Все еще получение ошибки: Msg 8114, уровень 16, состояние 5, строка 2 Ошибка преобразования типа данных nvarchar в float. – JsonStatham

+0

Попробуйте снова с моим редактированием. Если он не работает, поместите весь запрос (или sp, если это так) в ваш вопрос. –

1

вы не можете ожидать, чтобы иметь колонку, где иногда значение является VARCHAR и и в другое время с плавающей точкой, так что вы можете конвертировать целые результаты в ТОГДА к NVARCHAR как:

CASE 
    WHEN (Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)- FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)))=0 
    THEN cast('unknown number' as nvarchar) 
    WHEN (Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)- FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)))> 0 AND (Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)- FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar)))<=0.25 
    THEN CAST((0.25+FLOOR(Cast(CONVERT(DECIMAL(10,2),(totaleffort/7.40)) as nvarchar))) as nvarchar) 

посмотреть на последней строке

+0

Это не работает – JsonStatham

+0

Это то же сообщение об ошибке, или вы не получаете ожидаемый результат? – Vikram

0

почему не просто:

WHEN CONVERT(DECIMAL(10,2),(totaleffort/7.40)) - FLOOR(CONVERT(DECIMAL(10,2),(totaleffort/7.40)))) = 0 THEN 'unknown number' 

наблюдение:

почему бы вам не изменить (expression) > 0 and (same expression) <=0.25 к (expression) between 0 and 0.25

на первый примере вы вычислительные такое же выражение дважды без причины

0

я замечаю, что оба предлагаемых ответы делают преобразование в «Когда» части пункта без преобразования значения сравнения в NVARCHAR также. Возможно, поэтому вы все еще видите ошибки с предоставленным кодом.

Я бы предположил, что вы оставите тип данных один в предложении «Когда» (кажется, что «правильное» сравнение является числовым), но все результаты «Then»/«Else» нуждаются в преобразовании в типы символов, как SQL не может смешивать и сопоставлять типы данных в одном столбце.

Немного дополнительного ввода ... вне сферы действия вопроса, я понимаю :-) Если это для отчета, я предлагаю изменить интерфейс отчета вместо изменения SQL. Оставляя только тип данных на уровне представления/процедуры/функции, структура данных будет более многоразовой/расширяемой и вычислений/агрегатов, которые должно использовать нулевое значение, будет вести себя так, как ожидалось, без «обратного преобразования». Если вы должны изменить SQL-сторону, а не на интерфейс, я бы предложил включить как столбцы «отчетные», так и «фактические значения» в структуре SQL-side, чтобы вы не потеряли никакой функциональности, удалив нулевые значения и изменение типов данных.

Смежные вопросы