我有一个返回列表的存储过程。变量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语句中将字段正确转换为空白。
谢谢!
答案 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来解决问题并可能获得更快的速度。