6

我在 UPDATE 中使用子查询:

UPDATE tableA 
SET x,y,z = ( (SELECT x, y, z 
               FROM tableB b
               WHERE tableA.id = b.id
                 AND (tableA.x != b.x
                      OR tableA.y != b.y
                      OR tableA.z != b.z))) );

我的问题是,如果子查询不返回任何行会发生什么?它会使用空值进行更新吗?

其次,有没有更好的方法来写这个。我基本上是从 tableB 更新 tableA 中的三个字段,但是只有在三个字段中的任何一个不同时才应该进行更新。

4

2 回答 2

6

如果子查询不返回任何行会发生什么?它会使用空值进行更新吗?

是的-您可以像这样测试:

update YourTable
set col1 = (select 1 where 1=0)

这将用 NULL 填充 col1。如果子查询返回多行,例如:

update YourTable
set col1 = (select 1 union select 2)

数据库将产生错误。

其次,有没有更好的方法来写这个。我基本上是从 tableB 更新 tableA 中的三个字段,但是只有在三个字段中的任何一个不同时才应该进行更新。

直觉上我不会担心性能。如果你真的想避免更新,你可以这样写:

UPDATE a
SET x = b.x, y = b.y, z = b.z
FROM tableA a, tableB b 
WHERE a.id = b.id AND (a.x <> b.x OR a.y <> b.y OR a.z <> b.z)

WHERE子句防止使用 NULL 进行更新。

于 2009-12-01T23:09:46.423 回答
0

在我使用的 informix 上,Andomar 解决方案的一个变体:

UPDATE a
SET x,y,z = ( (SELECT x, y, z 
               FROM tableB b
               WHERE tableA.id = b.id) )
WHERE tableA.id IN (SELECT fromTable.id
                    FROM tableA toTable, tableB fromTable
                    WHERE toTable.id = fromTable.id
                      AND ((toTable.x <> fromTable.x) 
                           OR (toTable.y <> fromTable.y)
                           OR (toTable.z <> fromTable.z))
于 2009-12-02T15:13:57.623 回答