Oracle SQL更新查询仅在值为空时才更新。

3
我有以下查询,只有当值为空时才更新。
是否可以将所有这些查询合并为单个查询?
UPDATE test
SET test1 = 'hello'
WHERE test1 IS NULL

并且。
UPDATE test
SET test2 = 'world'
WHERE test2 IS NULL
3个回答

10

您可以尝试:

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

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


触发器问题将与您使用COALESCE或NVL有关。在我看来,对于简单的空值测试,COALESCE过于繁琐。 - Ollie
你能定义一下“标准”吗?我相信NVL在Oracle中已经使用了相当长的时间,这是一个关于Oracle的问题。 - Ollie
1
抱歉,符合ANSI标准。此外,NVL会评估两个参数,而COALESCE则返回第一个非空值,只评估到该点。 - David Faber
我喜欢关于NVL评估两个参数和COALESCE只评估第一个非空值的观点。对于这个问题来说,这可能几乎不可察觉,但是在NVL或类似函数中使用子查询的情况下,它可能更加高效。 - Ollie
我欣赏这些差异,并且在某些情况下,使用COALESCE比NVL更值得,但是从可读性和明显的代码意图方面来看,可以认为NVL更能描述代码的目的。因人而异。 - Ollie
显示剩余3条评论

2
UPDATE test
   SET test1 = COALESCE(test1, 'hello')
     , test2 = COALESCE(test2, 'hello')
 WHERE test1 IS NULL OR test2 IS NULL

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


1
@Tom,只有在test1为空时,它才会更新test1,而不管test2中是否有内容。 - Ollie
在这种情况下,我还需要使用 WHERE 吗?当然,我会添加一个 WHERE user_id = 'myuserid' - Tom
从技术上讲,如果test1不为空,则会更新它,但会将其设置为当前值。这就是触发器可能成为问题的原因。即使您将列更新为其当前值,它们也会触发。 - David Faber
没错,我考虑的是当有一个UPDATE OF test1触发器的情况;即使只有test2为空,它也会触发。 - David Faber
尝试使用COALESCE时出现了ORA-12704:字符集不匹配的错误,但在同一查询中使用NVL时却没有任何问题。 - vapcguy
显示剩余2条评论

0
UPDATE test
SET Test1 = COALESCE(test1, 'hello'),
    Test2 = COALESCE(test2, 'world')
WHERE test1 IS NULL OR
      test2 IS NULL

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接