【问题标题】:Oracle SQL update query only update values if they are nullOracle SQL 更新查询仅更新为空的值
【发布时间】:2012-03-09 11:35:53
【问题描述】:

我有以下查询,仅当它们为空时才更新值。

是否可以将所有这些放在一个查询中?

UPDATE test
SET test1 = 'hello'
WHERE test1 IS NULL

UPDATE test
SET test2 = 'world'
WHERE test2 IS NULL

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    你可以试试:

    UPDATE test
       SET test1 = NVL(test1, 'hello'),
           test2 = NVL(test2, 'world')
     WHERE test2 IS NULL
        OR test1 IS NULL;
    

    尽管它可能会触发您的更新触发器,即使对于实际上未更改的行也是如此。

    【讨论】:

    • 无论您使用 COALESCE 还是 NVL,触发问题都将是相关的。恕我直言,COALESCE 对于简单的空测试来说太过分了。
    • 我选择 COALESCE 而不是 NVL 的唯一原因是它是标准的,而后者不是。无论哪种方式对我来说都很好。 :)
    • 你能定义“标准”吗?我相信 NVL 已经被 Oracle 使用了很长时间,这是一个 Oracle 的问题。
    • 对不起,ANSI 标准。 NVL 也会计算两个参数,而 COALESCE 返回第一个非空值,只计算到那个点。
    • 我喜欢关于 NVL 仅对第一个非空值评估参数和 COALESCE 的观点。对于这个问题,它会很明显,但在 NVL 或类似的子查询的情况下,它可能会更有效。
    【解决方案2】:
    UPDATE test
       SET test1 = COALESCE(test1, 'hello')
         , test2 = COALESCE(test2, 'hello')
     WHERE test1 IS NULL OR test2 IS NULL
    

    COALESCE() 在这种情况下与 NVL() 的工作方式类似——返回第一个非空值。

    【讨论】:

    • 如果 test1 为 null 并且 test2 = "abc" 时,这只会更新 test1 吗??
    • @Tom,它只会在 test1 为 null 时更新它,而不管 test2 中有(或不在)什么。
    • 在这种情况下我还需要 where 吗?...我当然会添加一个 WHERE user_id = 'myuserid'
    • 从技术上讲,如果 test1 不为空,它将更新它,但会将其设置为当前值。这就是为什么触发器可能是一个问题。即使您将列更新为其当前值,它们也会触发。
    • 如果您不包含 WHERE 子句来测试空值,则 test1 和 test2 都不为空的行将不必要地更新。
    【解决方案3】:
    UPDATE test
    SET Test1 = COALESCE(test1, 'hello'),
        Test2 = COALESCE(test2, 'world')
    WHERE test1 IS NULL OR
          test2 IS NULL
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多