我正在修改SQL Server中的现有存储过程并尝试提出一个应该采用条件WHERE
的查询,具体取决于其中一个输入参数是null
还是有值。< / p>
存储过程需要三个输入参数
@FromDate
@ToDate
@PersonnelNo
@FromDate
和@ToDate
将始终具有值,并且将成为WHERE
条件的一部分,但@PersonnelNo
可以为null或可以保留值。
当@PersonnelNo
为空时,我希望所有用户都在给定@FromDate
和@ToDate
日期,但当参数@PersonnelNo
有值时,我希望存储过程为仅返回该用户的数据。
我尝试了以下两种方法,但只有在@PersonnelNo
输入值时才能正常工作(正确提供一个用户记录)。如果我将@PersonnelNo
作为null
输入,则不会返回任何记录,而是我想要所有用户。
我想知道我哪里出错了,或者根据我目前采用的方法是否可行?
SELECT FirstName,
LastName,
PersonnelNum,
RecCreatedOn
FROM [test].Person
WHERE RecCreatedOn BETWEEN @FromDate AND @ToDate
AND (
(ISNULL(@PersonnelNo, 0) != 0 AND PersonnelNum = @PersonnelNo)
)
和一个略有不同的WHERE子句
WHERE RecCreatedOn BETWEEN @FromDate AND @ToDate
AND ((@PersonnelNo IS NOT NULL) AND PersonnelNum = @PersonnelNo)
答案 0 :(得分:4)
这可以说,如果@PersonnelNo为null,则用PeronnelNum替换它。 PersonnelNum将始终等于PersonnelNum,因此如果@PersonnelNo为null,则此条件将始终为true。
SELECT FirstName,
LastName,
PersonnelNum,
RecCreatedOn
FROM [test].Person
WHERE RecCreatedOn BETWEEN @FromDate AND @ToDate
AND (@PersonnelNo is null or PersonnelNum = @PersonnelNo)
您先前尝试的说明:
ISNULL(@PersonnelNo, 0) != 0 AND PersonnelNum = @PersonnelNo
如果@PersonnelNo为null,则变为:
0 != 0 and PersonnelNum = 0
。false and false
false
如果@PersonnelNo是(例如)1则变为:
1 != 0 and PersonnelNum = 1
。true and true (for the row where PersonnelNum is 1)
true
所以你会看到第1个人的行。
(@ PersonnelNo IS NOT NULL)AND PersonnelNum = @PersonnelNo
如果@PersonnelNo为null,则变为:
(null is not null) and PersonnelNum = null
。false and false
false
如果@PersonnelNo是(例如)1则变为:
1 is not null and PersonnelNum = 1
。true and true (for the row where PersonnelNum is 1)
true
有效的方法:
PersonnelNum = coalesce(@PersonnelNo,PersonnelNum)
(@PersonnelNo is null or PersonnelNum = @PersonnelNo)
虽然上述方法之间存在细微差别。如果PersonnelNum
可以为空,则可能会得到不同的结果;即coalesce
方法不包括此列中具有空值的行,而第二种方法将包含空值。