2016-12-01 69 views
3

当我运行此查询我所期望的结果将是“错误的”在ISNULL函数T-SQL意外行为

IF isnull(0,'') = '' 
     select 'true' 

else 
    select 'false' 

但SQL Server告诉我,“真”,为什么?

+2

因为ISNULL:

SELECT CONVERT(INT, '') 

回报0,所以如果你想要把0作为NULL,你可以使用NULLIF0=0是真的

(0,'')返回整数0,并且如果将第二个操作数也作为整数检查:select cast(''as integer),i t也返回0.你不应该使用不同的类型,这会以这种转换问题结束。 –

+0

为什么你这样使用'ISNULL()'?在WHERE或SELECT语句中使用这样的代码将空值转换为其他值会强制进行全表扫描。在'SELECT'语句中使用它是不可能的 –

+0

@MarcGuillot但是阅读[this](https://connect.microsoft.com/SQLServer/feedbackdetail/view/347996/converting-an-empty-string-0-int -does-not-honor-round-trip-conversion-undocumented),它表示将一个空字符串转换为数字会导致错误。 –

回答

0

当只有两个值(即NULL和0)时,ISNULL是相同的,所以在IF条件下它将为真,并且将打印选择“真”。

2

在这种情况下,ISNULL(0,'')返回一个整数。 SQL Server会将第二个参数强制转换为一个整数,即0。因此,0 = 0,因此结果为TRUE。直接比较,以0也将返回true:

IF 0 = '' 
     select 'true' 

else 
    select 'false' 

使用ISNULL和NULL这样是不寻常的。 WHERE子句中的ISNULL(someColumn='')函数将阻止优化器使用覆盖someColumn的任何索引,从而强制执行扫描而不是索引查找。

在SELECT中使用IF语句是不可能的。即使在CASE语句中,最好显式检查NULL,而不是应用这种转换。

+0

好的,thx解释。我试过“select cast(''as int)”,它返回0 – star

+0

@Star为什么你这样做呢?这个'IF ISNULL'结构要解决的实际问题是什么?最有可能的是,有更简单快捷的方法来做到这一点 –

2

对于您的情况,当比较两个值时,''将首先转换为int。以下:

DECLARE @i INT = 0 
IF NULLIF(ISNULL(@i, ''), 0) = '' 
    SELECT 'true' 
ELSE 
    SELECT 'false' 

这将返回'false'