将数据类型varchar转换为float时出错

时间:2012-02-28 10:40:18

标签: sql sql-server sql-server-2008 ssrs-2008

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。

我有一个零值的新要求,当值= 0然后我需要显示文本'未知数'我试图添加一个额外的case语句但是查询无法运行并出现错误:< / p>

  

将数据类型varchar转换为float时出错。

有没有人为我推荐

5 个答案:

答案 0 :(得分: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,

答案 1 :(得分: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)

看最后一行

答案 2 :(得分: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将返回{{1}否则它将返回结果;

  • 现在NULL正好相反:如果第一个参数是ISNULL,则返回第二个参数,否则返回第一个参数。

因此,通过这一系列转换,零实际上变为NULL

答案 3 :(得分: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

在第一个例子中,你无缘无故地计算两次相同的表达式

答案 4 :(得分:0)

我注意到所提供的答案都在子句的“When”部分进行转换,而不将比较值转换为nvarchar。这可能就是您仍然看到提供的代码出错的原因。

我建议您将数据类型单独保留在'When'子句中(似乎'正确'比较是数字),但所有'Then'/'Else'结果都需要转换为字符类型作为SQL不能在同一列中混合匹配数据类型。

只是一点额外的输入...超出了问题的范围,我意识到:-)如果这是一个报告,我建议改变报告界面而不是改变SQL。将数据类型单独保留在视图/过程/功能级别将使数据结构更可重用/可扩展,并且 应使用零值的计算/聚合将按预期运行,而不必“反向转换” 。如果你必须改变SQL端而不是接口端,我建议在SQL端结构中同时包含'report pretty'和'actual value'列,这样你就不会因删除零值而丢失任何功能。改变数据类型。