当可能存在空值时,如何检查SQL server 2012中是否存在记录?

当可能存在空值时,如何检查SQL server 2012中是否存在记录?,sql,sql-server,where-clause,Sql,Sql Server,Where Clause,当列值可能为NULL时,如何处理SQL Server 2012中的SELECT语句 如果记录不存在,我试图通过JDBC有条件地插入记录,如果记录存在,则返回与该记录关联的ID。为了简单起见,我选择使用SELECT查询,然后是INSERT查询 我的SELECT查询看起来是这样的,除了a、b、c、d、e对应于有意义的名称,请使用您的想象力 SELECT id FROM dim_repository WHERE a = ? AND b = ? AND c = ? AND d =

当列值可能为NULL时,如何处理SQL Server 2012中的SELECT语句

如果记录不存在,我试图通过JDBC有条件地插入记录,如果记录存在,则返回与该记录关联的ID。为了简单起见,我选择使用SELECT查询,然后是INSERT查询

我的SELECT查询看起来是这样的,除了a、b、c、d、e对应于有意义的名称,请使用您的想象力

SELECT id 
FROM dim_repository 
WHERE a = ? 
  AND b = ? 
  AND c = ? 
  AND d = ? 
  AND e = ?
但是,如果a为NULL,那么查询将返回一个空的resultset,因为a=NULL不是有效的查询,也就是说,因为NULL和标量值使用了不同的动词

修复查询的唯一方法是添加如下条件选择吗

SELECT id 
FROM dim_repository 
WHERE (a = ? OR a IS ?) 
  AND (b = ? OR b IS ?) 
  AND (c = ? OR c IS ?) 
  AND (d = ? OR d IS ?)
  AND (e = ? OR e IS ?)

这种方法是有效的,尽管由于我正在处理的表有16个不同的列,我不太愿意在SELECT调用中使用30个条件语句。

如果您知道有一些不可能的值可以替换为null,例如0表示自动递增列,那么可以使用ISNULL:

WHERE a = ISNULL(@parameter,0) AND ...
但是,最安全的做法是明确说明自己在做什么,将附加的AND子句放入空检查:

WHERE (a = @parameter OR @parameter IS NULL) AND ...
编辑:最近的活动促使我重新阅读我接受的答案,我不知道我在写的时候在想什么。当然,如果你小心的话,它会起作用,但这不是一个好的解决方案。相反,应使用intersect和except功能,因为它们被设计为优雅地处理空比较:

declare @a int = null;
declare @b int = null;

select Data.*
from (values
    (1, 1)
  , (1, null)
  , (null, 1)
  , (null, null)
) as Data (a, b)
where exists (
          select @a, @b
          intersect
          select Data.a, Data.b 
      );
我还注意到@hvd实际上在评论中分享了这个解决方案,所以我希望你听从他的建议,而不是我的

最初糟糕的回答是:我认为这符合你的要求,但需要注意的是,你必须小心选择哪个值作为后备值。此处选择0很糟糕,因为0可能是表中的有效值

declare @i1 int = null;
declare @i2 int = null;

select Data.*
from (values
    (1, 1)
  , (1, null)
  , (null, 1)
  , (null, null)
) as Data (a, b)
where Coalesce(Data.a, 0) = Coalesce(@i1, 0)
  and Coalesce(Data.b, 0) = Coalesce(@i2, 0);

您可以考虑使用一个清洁器WHERE子句:ISNULLa,=?和ISNULLb,=?以此类推。在SQL Server不支持的标准SQL中,x和y没有区别,如果x=y,这是正确的,除了两个空值比较相等。请参阅,特别是John Keller的答案,了解如何为SQL Server重写它。注意:在您的示例中,它可以写成WHERE exists SELECT a、b、c、d、e INTERSECT SELECT?、?、?、?、?。如果您添加更多的列,它的伸缩性非常好。@scrapingfinity我认为您假设如果参数为null,则应接受a的任何值。或者,如果a为null,则无论传递什么参数,都应始终返回该行。这不是我从这个问题中得到的。我得到的印象是,如果参数为null,则只应返回a为null的记录。@hvd True,这是一种可能性,也许OP的一些澄清会有所帮助。@hvd这是正确的,如果我理解正确,是的。我想先看看表中是否存在行,然后再插入行,以使null不会破坏SELECT语句。Hm。我希望不必使用2n-1条件,其中n等于表中的列数。这就是SQL。您的问题不清楚您是在尝试空值检查表中的参数还是值。如果是这些参数,你可能会侥幸逃脱ISNULL@parameter,0或任何已知的不可能值。请参阅更新。