使用参数调整导致 NULL 评估的 WHERE 子句
Using parameter to adjust WHERE clause resulting in NULL evaluation
我正在尝试使用应用程序传递的参数来确定查询中的 WHERE 子句。根据参数中的值,它将确定 WHERE。 3 个 WHERE 选项中的 2 个导致评估为 NULL。下面是 3 个潜在的 WHERE 语句,每个语句在独立应用时都有效。
WHERE sSC.Description IS NOT NULL
WHERE sSC.Description IS NULL
WHERE sSC.Description = @Signature
我尝试执行此多个变体,但所有变体的语法都不正确。这是最新的。
DECLARE @Signature AS VARCHAR (max)
SET @Signature = 'XXXPARAMETER1XXX'
Select *
FROM Operations.dbo.sSignatureClassification AS sSC
WHERE
CASE @Signature
WHEN 'Without' THEN (sSC.Description IS NOT NULL)
WHEN 'With' THEN (sSC.Description IS NULL)
ELSE (sSC.Description = @Signature)
END
这会起作用:
WHERE (@Signature = 'Without' AND sSC.Description IS NOT NULL)
OR (@Signature = 'With' AND sSC.Description IS NULL)
OR (@Signature <> 'Without' AND @Signature<>'With' AND sSC.Description = @Signature)
但是,您应该考虑将查询分开,因为如果缓存了查询计划,您可能会发现它的执行效果不佳。
如果这是在存储过程中,您应该像这样分解它:
DECLARE @Signature AS VARCHAR (max)
SET @Signature = 'XXXPARAMETER1XXX'
IF (@Signature = 'With')
SELECT *
FROM Operations.dbo.sSignatureClassification AS sSC
WHERE sSC.Description IS NULL
ELSE
IF (@Signature = 'Without')
Select *
FROM Operations.dbo.sSignatureClassification AS sSC
WHERE sSC.Description IS NOT NULL
ELSE
Select *
FROM Operations.dbo.sSignatureClassification AS sSC
sSC.Description = @Signature
这将导致 SQL 服务器生成 3 个单独的查询计划,可能前两个将使用索引扫描(查找 null/not null),而最后一个将使用索引查找。实际上,第一个也可能使用索引查找。检查 SQL Profiler 以确保。
在你需要条件的地方,在你的情况下,我建议使用简单的 OR:
DECLARE @Signature AS VARCHAR (max)
SET @Signature = 'XXXPARAMETER1XXX'
Select *
FROM Operations.dbo.sSignatureClassification AS sSC
WHERE
(@Signature= 'Without' AND sSC.Description IS NOT NULL) OR
(@Signature= 'With' AND sSC.Description IS NULL) OR
(@Signature<> 'Without' AND @Signature<> 'With' AND sSC.Description = @Signature)
我正在尝试使用应用程序传递的参数来确定查询中的 WHERE 子句。根据参数中的值,它将确定 WHERE。 3 个 WHERE 选项中的 2 个导致评估为 NULL。下面是 3 个潜在的 WHERE 语句,每个语句在独立应用时都有效。
WHERE sSC.Description IS NOT NULL
WHERE sSC.Description IS NULL
WHERE sSC.Description = @Signature
我尝试执行此多个变体,但所有变体的语法都不正确。这是最新的。
DECLARE @Signature AS VARCHAR (max)
SET @Signature = 'XXXPARAMETER1XXX'
Select *
FROM Operations.dbo.sSignatureClassification AS sSC
WHERE
CASE @Signature
WHEN 'Without' THEN (sSC.Description IS NOT NULL)
WHEN 'With' THEN (sSC.Description IS NULL)
ELSE (sSC.Description = @Signature)
END
这会起作用:
WHERE (@Signature = 'Without' AND sSC.Description IS NOT NULL)
OR (@Signature = 'With' AND sSC.Description IS NULL)
OR (@Signature <> 'Without' AND @Signature<>'With' AND sSC.Description = @Signature)
但是,您应该考虑将查询分开,因为如果缓存了查询计划,您可能会发现它的执行效果不佳。
如果这是在存储过程中,您应该像这样分解它:
DECLARE @Signature AS VARCHAR (max)
SET @Signature = 'XXXPARAMETER1XXX'
IF (@Signature = 'With')
SELECT *
FROM Operations.dbo.sSignatureClassification AS sSC
WHERE sSC.Description IS NULL
ELSE
IF (@Signature = 'Without')
Select *
FROM Operations.dbo.sSignatureClassification AS sSC
WHERE sSC.Description IS NOT NULL
ELSE
Select *
FROM Operations.dbo.sSignatureClassification AS sSC
sSC.Description = @Signature
这将导致 SQL 服务器生成 3 个单独的查询计划,可能前两个将使用索引扫描(查找 null/not null),而最后一个将使用索引查找。实际上,第一个也可能使用索引查找。检查 SQL Profiler 以确保。
在你需要条件的地方,在你的情况下,我建议使用简单的 OR:
DECLARE @Signature AS VARCHAR (max)
SET @Signature = 'XXXPARAMETER1XXX'
Select *
FROM Operations.dbo.sSignatureClassification AS sSC
WHERE
(@Signature= 'Without' AND sSC.Description IS NOT NULL) OR
(@Signature= 'With' AND sSC.Description IS NULL) OR
(@Signature<> 'Without' AND @Signature<> 'With' AND sSC.Description = @Signature)