WHERE ISNULL 不会带来目标值为 NULL

时间:2021-05-31 16:17:39

标签: sql sql-server database

标题只解释了我的第一次尝试,我想不出如何准确地表达问题/我的需求。

我有餐桌工作:

CREATE TABLE [dbo].[job] 
(
    [jobId]      INT IDENTITY(1,1) PRIMARY KEY,
    [contractId] INT NOT NULL,
    [districtId] INT NULL,
    [address]    NVARCHAR (255) NULL
);

我正在尝试创建一个函数,其中可以选择性地传递所有列值以执行过滤器搜索。

到目前为止我有:

DECLARE
    @jobId          INT,
    @contracId      INT,
    @districtId     INT,
    @addressPart    NVARCHAR(255)

SELECT 
    [jobId],
    [contractId],
    [districtId],
    [address]   
FROM
    [dbo].job
WHERE 
    jobId = ISNULL(@jobId,jobId)
    AND contractId = ISNULL(@contracId, contractId)
    AND [address] LIKE '%' + ISNULL(@addressPart, [address]) + '%'

这是有效的,但是因为 districtId 表中的 Job 可以为 null 执行与 contractId 相同的 ISNULL where 子句导致查询只返回记录 where {{ 1}} 不为空,因为 '=' 条件不适用于空值。

我试过使用 districtId

COALESCE

但是如果没有指定 AND COALESCE(districtId, 0) = COALESCE(@districtId, 0) ,这会导致查询只选择 districtId 为空的记录。如果设置了“地区”,它会选择带有 districtId 的行。但这最终是不好的,因为如果设置了与记录匹配的任何其他变量,如果该记录为空 districtId,则不会被选中。

我也试过使用 OR

districtId

但是当 AND (districtId = ISNULL(@districtId, districtId) OR districtId IS NULL) 为 null 时,这会返回所有内容,但是如果设置了 districtId,它将获取该记录,但仍会返回所有 districtId 为 null 的记录.

我什至想不出如何用脏的 CASE 语句来做这件事,因为我需要做 districtId 并且一旦我这样做 '=' 它不会像它需要的那样工作在某种程度上检查 null 是否为 null,而 '=' 不能这样做。

2 个答案:

答案 0 :(得分:3)

您必须单独检查 @districtId 是否为 null,在这种情况下,条件应返回 true

AND (@districtId IS NULL OR districtId = @districtId)

答案 1 :(得分:0)

您仍然需要在 COALESCE 中包含该列来处理 param = 列值

 AND COALESCE(districtId ,0) = COALESCE(@districtId, districtId,0)