标题只解释了我的第一次尝试,我想不出如何准确地表达问题/我的需求。
我有餐桌工作:
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,而 '=' 不能这样做。
答案 0 :(得分:3)
您必须单独检查 @districtId
是否为 null
,在这种情况下,条件应返回 true
:
AND (@districtId IS NULL OR districtId = @districtId)
答案 1 :(得分:0)
您仍然需要在 COALESCE 中包含该列来处理 param = 列值
AND COALESCE(districtId ,0) = COALESCE(@districtId, districtId,0)