我有一个表更新字段时的值不另一个表中的字段相匹配的更新查询。
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
不等于任何东西-甚至包括NULL
。 NULL
的字面意思是该值是未知的。
这意味着,即使a.field1
和b.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