数字字段被视为varchar。将varchar值'24 .00'转换为数据类型int时转换失败

时间:2016-02-20 16:43:30

标签: sql sql-server-2008 tsql

我遇到了这条SQL的问题:

SELECT 
    (CASE 
        WHEN u.password IS NULL 
          THEN 'GUEST' 
          ELSE 'CUSTOMER' 
     END) as STATUS, 
    u.date_created, u.name as UserName, u.password, u.email, 
    r.token as Currency, 
    (CASE 
       WHEN u.balance > 0 
         THEN LEFT(u.balance, LEN(u.balance) - 2) + '.' + RIGHT(u.balance, 2)
         ELSE 0 
     END) as Balance
FROM 
    [user] u
INNER JOIN 
    [region] r ON r.currency_id = u.balance_currency

显示此错误:

  

将varchar值'24 .00'转换为数据类型int时,转换失败。

当我添加以下行时,它开始发生:

(CASE WHEN u.balance >0 THEN left(u.balance,len(u.balance)-2)+'.'+right(u.balance,2)
ELSE 0 END) as Balance

该行试图将值为2400的u.balance转换为24.00仅当值大于0.这是一个数字(10,0)字段,所以我不确定为什么它使用24.00并考虑它是一个varchar。任何帮助将不胜感激!谢谢!

2 个答案:

答案 0 :(得分:1)

case表达式应该返回相同的数据类型。在这种情况下,请使用'0'而不是数值0,因为您要在varchar中返回when

CASE WHEN u.balance >0 THEN left(u.balance,len(u.balance)-2)+'.'+right(u.balance,2)
ELSE '0' END

答案 1 :(得分:1)

嗯,将数字存储为字符串通常是一个坏主意。我认为你可以通过这样的方式获得理想的行为:

(case when isnumeric(u.balance) = 0
      then '0'
      when cast(u.balance as float) > 0.0
      then stuff(u.balance, len(u.balance - 2), 0, '.')
      else '0'
 end)

但是,我建议您重新考虑将数字存储为字符串。

注意:您只需使用0.0代替常量而不是0来修复代码版本。