当可能存在空值时,如何检查SQL server 2012中是否存在记录?
当列值可能为NULL时,如何处理SQL Server 2012中的SELECT语句 如果记录不存在,我试图通过JDBC有条件地插入记录,如果记录存在,则返回与该记录关联的ID。为了简单起见,我选择使用SELECT查询,然后是INSERT查询 我的SELECT查询看起来是这样的,除了a、b、c、d、e对应于有意义的名称,请使用您的想象力当可能存在空值时,如何检查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 =
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或任何已知的不可能值。请参阅更新。