【问题标题】:Update via subquery, what if the subquery returns no rows?通过子查询更新,如果子查询没有返回行怎么办?
【发布时间】:2010-12-22 04:58:14
【问题描述】:

我在 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 中的三个字段,但只有在三个字段中的任何一个不同时才会更新。

【问题讨论】:

  • 这个更新应该基于 tableB 的连接参数还是“笛卡尔更新”?
  • the update should only happen if any of the three fields are different. 对我来说听起来像是 where 子句...

标签: sql database subquery sql-update informix


【解决方案1】:

在我使用的 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))

【讨论】:

    【解决方案2】:

    如果子查询返回会发生什么 没有行?它会更新吗 空值?

    是的——你可以这样测试:

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

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

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

    数据库会产生错误。

    其次,有没有更好的方法 写这个。我基本上在更新 表B中表A中的三个字段, 但更新应该只发生在 这三个字段中的任何一个都是不同的。

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

    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 进行更新。

    【讨论】:

    • 这看起来很棒,除了,我忘了提到我使用的是 informix IDS 11.5,而且我不相信 informix 在 UPDATE 中支持 FROM 或在 UPDATE 中加入。
    • @prmatta:我认为 Informix 确实支持 FROM in UPDATE;我已经删除了 INNER JOIN。
    • @Andomar,我不认为是这样,至少不是我的。文档说确实如此,但我一直收到语法错误。我已将 sql 更新为没有 froms 和 joins 的内容并将其作为答案放入,如果它看起来不错,请告诉我。
    • @prmatta:您的解决方案看起来可以很好地解决 Informix 的限制!
    猜你喜欢
    • 1970-01-01
    • 2021-12-09
    • 1970-01-01
    • 2015-01-08
    • 2014-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-02
    相关资源
    最近更新 更多