通过子查询更新,如果子查询没有返回任何行,该怎么办?

时间:2009-12-01 22:12:53

标签: sql database subquery sql-update informix

我在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))) );

我的问题是,如果子查询没有返回任何行,会发生什么?它是否会使用null进行更新?

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

2 个答案:

答案 0 :(得分: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进行更新。

答案 1 :(得分: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))