SQL-Null结果在使用variable = null执行时不返回select语句,但在硬编码时执行

时间:2015-04-24 10:27:14

标签: sql sql-server select null

我有一个返回列表的存储过程。变量IS2000PolicyNo可以具有来自tblQuote的Null结果。 这是一个简化的片段,仅显示导致问题的变量。

@IS2000PolicyNo	int,

   IF @IS2000PolicyNo = -1 
SET @IS2000PolicyNo = NULL	
	
   BEGIN TRY
SELECT
	List= replace(	(  SELECT top 500 
                        cast(ISNULL(T.IS2000PolicyNo,'') as varchar)  + ';'
  FROM
	(SELECT DISTINCT
      Q.IS2000PolicyNo
  	FROM
	dbo.tblQuote	Q
  WHERE
  cast(isnull(Q.IS2000PolicyNo,'')as varchar)  LIKE '%'+ CAST(ISNULL(@IS2000PolicyNo,'')as varchar) + '%'	)

我执行传递-1的过程,IF语句将其转换为null,它应返回所有记录,但它会跳过IS2000PolicyNo的空值记录。 当我硬编码到Where语句使@ IS2000PolicyNo等于null时,它返回所有记录,包括空值。

WHERE
  cast(isnull(Q.IS2000PolicyNo,'')as varchar)  LIKE '%'+ CAST(ISNULL(null,'')as varchar + '%')

我也尝试过设置@IS2000PolicyNo = null而不是If语句,并且它不会返回空值。

我已逐步完成代码,并在If语句中将字段正确转换为空白。

谢谢!

2 个答案:

答案 0 :(得分:0)

我猜这个问题就在这一行:

cast(isnull(Q.IS2000PolicyNo,'')as varchar) LIKE '%' + CAST(ISNULL(@IS2000PolicyNo,'')as varchar) + '%'

这是非常可疑的:

  • 为什么值存储为整数但比较为字符串?
  • 为什么varchar()长度不合适? (非常危险的做法,但不是这里的问题。)
  • 当您传递-1 NULL时,您期望发生什么?

一种可能性就是将比较作为ints。遵循逻辑有点困难,但这可能就足够了:

((Q.IS2000PolicyNo = @IS2000PolicyNo) or coalesce(@IS2000PolicyNo, -1) = -1))

或者也许:

((Q.IS2000PolicyNo = '%' + cast(@IS2000PolicyNo as varchar(255)) + '%') or
 (coalesce(@IS2000PolicyNo, -1) = -1))

答案 1 :(得分:0)

在SQL Server中,ISNULL将输出转换为与输入相同的数据类型。由于您的参数是INT,因此返回类型是INT。看到它在行动,因为它返回0:

declare @foo as int;
set @foo = null;
select ISNULL(@foo,'');

要解决此问题,您应该将该参数CAST到ISNULL检查中的VARCHAR,而不是在其外部。

或者,使用ANSI标准COALESCE而不是ISNULL,您将不会遇到此问题。 A good explanation is here,具体来说:

  

COALESCE和ISNULL在确定数据类型方面有所不同   结果表达。

     

COALESCE表达式的数据类型是输入的数据类型   具有最高数据类型优先级的参数。如果所有输入都是   无类型的NULL文字,你会收到错误。

     

ISNULL表达式的数据类型是第一个的数据类型   输入。如果第一个输入是无类型的NULL文字,则数据类型为   结果是第二个输入的类型。如果两个输入都是   无类型的文字,输出的类型是INT。

我最后的想法是,如果你在整个查询中将它重新转换为VARCHAR,为什么参数是INT?您可以通过将参数的数据类型更改为VARCHAR来解决问题并可能获得更快的速度。