SQL Server是否真的评估案例表达式中的每个'then'子句?

时间:2013-04-25 07:57:02

标签: sql sql-server

我正在使用99%数字的遗留系统中的ItemNumber字段,但有一些记录包含字母。这些数字都用前导零填充,所以我认为我只是将它们作为bigint来解决这个问题,但当它到达带有字母的记录时会引发错误。

我认为下面的case语句会起作用,但它仍会引发错误。如果isnumeric(itemnumber)= 1条件不正确,为什么SQL Server会评估转换?

select case when isnumeric(itemnumber) = 1 
           then cast(itemnumber as bigint) 
           else itemnumber 
       end ItemNumber
from items

什么是最好的解决方法?

3 个答案:

答案 0 :(得分:3)

如果表达式为数字,则表达式会尝试将VARCHAR值转换为BIGINT,如果不是,则将值保留为原样。

由于您在CASE语句中混合数据类型,SQL Server会尝试将它们全部转换为BIGINT,但在非数字值上失败。

如果您只想省略非数字值,请删除ELSE子句:

SELECT  CASE ISNUMERIC(itemnumber)
        WHEN 1 THEN
                CAST(itemnumber AS BIGINT) 
        END
FROM    items

答案 1 :(得分:0)

也许是因为:

  

对于某些非数字字符,例如加号(+),减号( - )和有效货币符号(如美元符号($)),ISNUMERIC返回1。有关货币符号的完整列表,请参阅money和s​​mallmoney(Transact-SQL)。

http://msdn.microsoft.com/en-us/library/ms186272.aspx

答案 2 :(得分:0)

问题是你还在混合你的类型:

select case when isnumeric(itemnumber) = 1 
           then cast(itemnumber as bigint) --bigint
           else itemnumber --varchar or whatever 
       end ItemNumber --????
from items

您需要两列

select case when isnumeric(itemnumber) = 1 
           then cast(itemnumber as bigint) --bigint
           else -1 
       end NumericItemNumber 
from items

select case when isnumeric(itemnumber) = 1 
           then ''
           else itemnumber
       end StringItemNumber 
from items

然后,您需要构建一个同时包含int和varchars的查询