Oracle:有没有一种简单的方法可以在合并/更新语句中说“如果 null 保持当前值”?

Posted

技术标签:

【中文标题】Oracle:有没有一种简单的方法可以在合并/更新语句中说“如果 null 保持当前值”?【英文标题】:Oracle: Is there a simple way to say "if null keep the current value" in merge/update statements? 【发布时间】:2008-09-22 18:56:10 【问题描述】:

我对 oracle 的任何更高级功能的理解相当薄弱,但我认为这应该是可能的。

假设我有一个具有以下架构的表:

MyTable
  Id INTEGER,
  Col1 VARCHAR2(100),
  Col2 VARCHAR2(100)

我想用下面的写一个sproc

PROCEDURE InsertOrUpdateMyTable(p_id in integer, p_col1 in varcahr2, p_col2 in varchar2)

其中,在更新的情况下,如果p_col1、p_col2中的值为null,不会分别覆盖Col1、Col2

如果我有记录:

id=123, Col1='ABC', Col2='DEF'

exec InsertOrUpdateMyTable(123, 'XYZ', '098'); --results in id=123, Col1='XYZ', Col2='098'
exec InsertOrUpdateMyTable(123, NULL, '098');  --results in id=123, Col1='ABC', Col2='098'
exec InsertOrUpdateMyTable(123, NULL, NULL);   --results in id=123, Col1='ABC', Col2='DEF'

有没有什么简单的方法可以在没有多个 SQL 语句的情况下做到这一点?

我认为可能有一种方法可以使用 Merge 语句来做到这一点,尽管我只是稍微熟悉它。


编辑: 下面的 Cade Roux 建议使用 COALESCE,效果很好! Here are some examples of using the coalesce kewyord. 这是我的问题的解决方案:

MERGE INTO MyTable mt
    USING (SELECT 1 FROM   DUAL) a
    ON (mt.ID = p_id)
    WHEN MATCHED THEN
        UPDATE
           SET mt.Col1 = coalesce(p_col1, mt.Col1), mt.Col2 = coalesce(p_col2, mt.Col2)
    WHEN NOT MATCHED THEN
        INSERT (ID, Col1, Col2)
        VALUES (p_id, p_col1, p_col2);

【问题讨论】:

我认为 MERGE 语句包装器只是在这里模糊了一些东西。在这样的单行合并中,我会将更新分开并在其后捕获“如果 sql%notfound 然后插入”。 @Nick:合并后你会更好。其他人可能会在两个 SQL 语句之间弄乱你的数据 【参考方案1】:

更改要使用的调用或更新语句

nvl(newValue, oldValue)

为新的字段值。

【讨论】:

但是我必须在另一个 SQL 语句中取出 oldValue,除非你知道一些我不知道的事情【参考方案2】:

使用 MERGE 和 COALESCE? Try this link for an example

SET a.Col1 = COALESCE(incoming.Col1, a.Col1)
    ,a.Col2 = COALESCE(incoming.Col2, a.Col2)

【讨论】:

我该怎么做?!请告诉我。 不应该反过来吗? COALESCE 将返回第一个非空值,因此在这种情况下,一旦将值设置为某个值,它将永远不会设置为其他任何值。我认为 nvl 声明在这种情况下更准确。 是的,我将更正我的代码以反转参数。对于两个值,NVL() 与 COALESCE() 相同(至少在 SQL Server 中 ISNULL() 与 COALESCE() 相同)。

以上是关于Oracle:有没有一种简单的方法可以在合并/更新语句中说“如果 null 保持当前值”?的主要内容,如果未能解决你的问题,请参考以下文章

有没有更快的方法在 oracle pl/sql 中每周对 120k 条记录执行合并?

有没有一种简单的方法可以在 Oracle 8 上转换句子案例中的字符串?还是我应该使用正则表达式?

合并多个sql更新语句(Oracle)

合并 ES6 地图/集的最简单方法?

Oracle 数据库实现数据合并:merge

有没有一种简单的方法来抑制 Oracle 中集合的 XML 行标记?