Nulls和MERGE语句:我需要将值设置为无穷大。怎么样?

时间:2010-12-22 13:41:02

标签: sql-server sql-server-2008 null

在SQL Server 2008中,我正在使用MERGE。一切都很好,除了我有2个可以为空的列。如果我传递一个空值并且目标不是null,则MERGE没有看到差异(对每个BOL的ev = null = false)。如果我在两边都使用IsNull(源和目标),但有可能错误评估值的问题。

我的意思是,如果我说:

WHEN MATCHED AND NOT (IsNull(tgt.C, 0) = IsNull(src.C, 0)) THEN

然后如果tgt.C为null且src.C = 0,则不会执行更新。无论我选择什么替代价值,我都会遇到这个问题。

我还尝试了“AND NOT(... true ...)”语法,因为BOL声明对null的评估结果为FALSE。但是,它们似乎实际上导致NULL并且不会导致我的多部分语句变为false。

我认为一种解决方案是使用NaN或-INF或+ INF,因为它们在目标中无效。但我找不到在SQL中表达这种方法的方法。

任何想法如何解决这个问题?

编辑:

以下逻辑解决了这个问题,但它很冗长,不会造成快速逃避:

declare @i int, @j int

set @j = 0
set @i = 0

if ISNULL(@i, 0) != ISNULL(@j, 0) OR 
    ((@i is null or @j is null) and not (@i is null and @j is null))
    print 'update';

9 个答案:

答案 0 :(得分:19)

您可以使用

WHEN MATCHED AND EXISTS (SELECT tgt.C EXCEPT SELECT src.C)

有关此问题的详情,请参阅this article

答案 1 :(得分:13)

您可以更改合并语句的ON部分,检查源和目标何时为空。

MERGE tgt
USING src
ON ( -- enter non-nullable columns to match on ...
    tgt.A = src.A
    AND (tgt.C = src.C OR (tgt.C IS NULL AND src.C IS NULL))
)
WHEN MATCHED -- ...

答案 2 :(得分:3)

实际上,这效果更好。只需添加另一个替换值作为OR: -

WHEN MATCHED AND 
    ( 
    NOT (IsNull(tgt.C, 0) = IsNull(src.C, 0)) OR NOT (IsNull(tgt.C, 1) = IsNull(src.C, 1)) 
    ) 
THEN ....

答案 3 :(得分:2)

WHEN MATCHED AND tgt.c <> src.c OR tgt.c IS NULL AND src.c IS NOT NULL OR tgt.c IS NOT NULL AND src.c IS NULL

答案 4 :(得分:2)

您是否尝试SET ANSI_NULLS OFF,这会使NULL=NULL返回true? This may create additional issues但它可能是一个脚本级别的解决方法(在运行proc之后将其关闭然后再打开)。

答案 5 :(得分:2)

这也有效,如果您想要检查多个列是否不同,可能会更好。

  MERGE @t2 a

  using @t1 b

  ON a.PK = b.PK

  WHEN MATCHED AND CHECKSUM(a.PK,a.VALUE)!= CHECKSUM(b.pk,b.VALUE)

  THEN UPDATE SET a.VALUE = b.VALUE;

答案 6 :(得分:0)

当值为null时,为什么不使用极不可能存在的值,而不是使用0? EG(IsNull(tgt.C,2093128301)。

数据类型为int,因此您可以使用......

答案 7 :(得分:0)

您可以在ON子句中检查是否为空:

MERGE TargetTable
USING (VALUES (0)) as s(x)
ON last_run is not null
WHEN not matched then
insert (last_run) values(getdate())
when matched then
update set last_run=getDate();

答案 8 :(得分:-1)

WHEN MATCHED AND
(
   NULLIF(tgt.C, src.C) IS NOT NULL OR NULLIF(src.C, tgt.C) IS NOT NULL
)
THEN