与SQL比较和空值问题(Issues with SQL comparison and null va

2019-08-21 08:50发布

我有一个表更新字段时的值不另一个表中的字段相匹配的更新查询。

UPDATE  table1
SET     a.field1 = b.field3
FROM    table1 a ,
        table2 b
WHERE   a.field2 = b.field2
        AND a.field1 <> b.field3

我遇到的问题是,它不拿起时a.field1为null,并且b.field3是一个值,或者如果a.field1是一个值,b.field3为空。

我已经通过添加以下解决此得到...

UPDATE  table1
SET     a.field1 = b.field3
FROM    table1 a ,
        table2 b
WHERE   a.field2 = b.field2
        AND ( a.field1 <> b.field3
              OR (a.field1 IS NOT NULL
              AND b.field3 IS NULL)
              OR (a.field1 IS NULL
              AND b.field3 IS NOT NULL)
            )

我的问题是围绕为什么这更中心的正在发生的事情,以及如何最好的结构,以便查询,以防止这种情况?

Answer 1:

问题是与NULL比较。 如果a.field1或b.field3为NULL,你需要使用is null或is not null的语句。 你可以使用默认值a.field1和b.field3与ISNULL功能。

ISNULL(a.field1,0) <> ISNULL(b.field3,0)

在这种情况下,存在用值0进行比较。

SELECT IIF(NULL = NULL, '真', '假') - 的结果为假。 惊人!



Answer 2:

东西比较空,结果甚至本身,始终是NULL(不是TRUE或FALSE)。 使用选项与EXISTS和EXCEPT运算符。

UPDATE table1
SET a.field1 = b.field3
FROM table1 a JOIN table2 b ON a.field2 = b.field2
WHERE EXISTS (
              SELECT a.field1
              EXCEPT
              SELECT b.field3
              )


Answer 3:

除了正确处理NULL逻辑,你需要将属于被括号一起应用多个条件

像这样的东西(不知道我理解你的条件完全一致)。

UPDATE  table1
SET     a.field1 = b.field3
FROM    table1 a ,
        table2 b
WHERE   a.field2 = b.field2
        AND (
              ( a.field1 <> b.field3)
              OR (a.field1 IS NOT NULL AND b.field3 IS NULL)
              OR (a.field1 IS NULL AND b.field3 IS NOT NULL)
            )


Answer 4:

蒂姆Shmelter就在他的评论中, NULL不等于任何东西-甚至包括NULLNULL的字面意思是该值是未知的。

这意味着,即使a.field1b.field3都是NULL ,条件a.field1 <> b.field3以及a.field1 = b.field3都将始终返回false。 试试吧,你会看到!

我认为这里的解决办法不在于在IFNULL的SQL Server的功能。 它位于更您的加盟逻辑。 你已经有你的解决方案,即在你的问题的第二个查询。 我会建议你是玩多一点用NULL值,这样你就可以明白真的是他们。



Answer 5:

您可以使用聚结在SQL Server中的列的值默认为一个非空值。 COALESCE返回列表中的第一个非空值。

UPDATE  table1
SET     a.field1 = b.field3
FROM    table1 a ,
        table2 b
WHERE   a.field2 = b.field2
        AND (
           coalesce(a.field1,-1) <> coalesce(b.field3, -1)
        )

我认为你的类型是数字,但可以使用其他数据类型。 我还假设,如果这两个值都为NULL,则两行是等价的。



Answer 6:

当您在查询编写a.field1 = b.field3你居然做出两个假设:字段1在表中必须包含在你的b表中的值和字段3还必须包含一个值。 这是不可能的比较值的“丢失信息和不适用的信息”。 这种比较的结果是未知的。 你可以看看关于更多信息维基百科 。



Answer 7:

这将检查列1和列2是平等的,另外用于皈依到VARBINARY在区分大小写的比较,如果没有必要,您可以将其删除。

--c1 = Length of Column1
--c2 = Length of Column2

ISNULL(NULLIF(CONVERT(VARBINARY(cl), LTRIM(RTRIM(Column1))), CONVERT(VARBINARY(c2),LTRIM(RTRIM(Column2)))), NULLIF(CONVERT(VARBINARY(c2),LTRIM(RTRIM(Column2))), CONVERT(VARBINARY(c1),LTRIM(RTRIM(Column1))))) IS NULL

您可以更改表达年底IS NOT NULL检查不平等的状况。

希望这有助于。



Answer 8:

另一种方法是使用校验功能

create table #temp
  (
    val1 varchar(255),
    val2 varchar(255)
  )

  insert into #temp values(NULL, NULL) 
  insert into #temp values(NULL, 'B') 
  insert into #temp values('A', NULL) 
  insert into #temp values('A', 'B') 
  insert into #temp values('A', 'A') 

  select *, 
  'Are Not Equal' = case 
   when val1 <> val2 or checksum(val1) <> checksum(val2) then 'true' 
   else 'false' end 
  from #temp


文章来源: Issues with SQL comparison and null values