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 条记录执行合并?