当源数据不变时,我们可以多次运行合并(Oracle)查询吗?

11 浏览
0 Comments

当源数据不变时,我们可以多次运行合并(Oracle)查询吗?

我正在使用以下查询:\n

MERGE INTO table2 b
     USING (
         SELECT column1,column2,column3
         FROM table1
     ) a
     ON (a.column3 = 'UPDATE')
     WHEN NOT MATCHED THEN
         INSERT (b.column1, b.column2) VALUES (a.column1,a.column2)
     WHEN MATCHED THEN
         UPDATE SET a.column1 = b.column1,a.column2=b.column2;

\n当table2为空时,第一次运行成功。\n如果我第二次运行,即使table1的数据没有更改,我仍然会收到错误消息unable to get a stable set of rows in the source tables。是否有解决这个错误的方法?\n如在此线程中所述,我尝试使用Distinct,但没有解决问题。\n我认为rowid应该可以解决这个问题,但不确定。\n谢谢

0
0 Comments

当源表不改变时,我们能否多次运行 merge(Oracle)查询的原因是因为在代码中的 ON 语句中,仅仅通过 a.column3 = 'UPDATE' 条件是不够的。我们需要明确地说明两个表之间的关系,以确保:

- Table1 中的某一行与 Table2 中的某一行匹配(UPDATE)

- 或者 Table1 中的某一行在 Table2 中没有匹配(INSERT)

这意味着 ON 子句必须以1:1或1:0的方式将两个表进行匹配,而不能是多对多。在下面的代码中,我假设 column1 是一个唯一标识符,如果是这样的话,它符合1:1的要求。

如果您没有办法唯一地标识每个表中的每一行,那么您需要改变数据结构以实现这一点。

注意,我在这里没有使用 UPDATE 值,因为它似乎不是必需的(您可能会提供更多解释为什么需要)。相反,对于 table1 中的每一行,它会在 table2 中搜索具有相同 column1 值的行。如果找到一个匹配的行,则执行更新操作;如果找不到匹配的行,则执行插入操作。

您之前的代码是说匹配条件为 a.column3 = 'UPDATE'。这意味着 table2 中的每一行都与 table1 中的每个 'UPDATE' 行进行匹配,导致它尝试使用 table1 中多行的值来更新 table2 中的同一行。同时,a.column3 <> 'UPDATE' 的每一行都会被插入到 table2 中。

我本来要写的是还应该提及0:1匹配,但是我决定自己验证一下 Oracle MERGE 是否有 WHEN NOT MATCHED BY SOURCE 子句。我很惊讶地发现它实际上没有这个子句,尤其是因为文档页面上说这个语句“可以避免多个 INSERT、UPDATE 和 DELETE DML 语句”。但是它继续透露,实际上 Oracle MERGE 中并没有 DELETE 子句!我想知道您是否知道我可能遗漏了什么。否则,文档似乎存在矛盾之处。

谢谢你的回答,我发现了两个表之间的共同点,并解决了问题。

0