当源没有改变时,我们可以多次运行合并(Oracle)查询

jav*_*oob 2 sql oracle

我使用以下查询,

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;
Run Code Online (Sandbox Code Playgroud)

当table2为空时,它第一次成功运行.如果我第二次运行,即使table1数据没有改变,我得到的错误是unable to get a stable set of rows in the source tables..这是一个解决方法,这个错误.

正如在这个帖子中提到的,我试过把它Distinct但它没有解决..

我认为rowid应该在这里解决目的..但不确定

谢谢

Mat*_*lie 5

ON (a.column3 = 'UPDATE') 还不够.

您需要说明两个表如何相互关联.这很重要,因为:
- Table1中的给定行匹配Table2中的一行(UPDATE)
- 或者,Table1中的给定行在Table2中没有匹配(INSERT)

这意味着该ON子句必须将两个表一起匹配为1:1或1:0.从来没有多少:很多.在下面的代码中,我将假设这column1是一个唯一的标识符.如果是这种情况,则符合1:1的要求.

如果您无法唯一标识每个表中的每一行,则需要更改数据以便可以.

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

请注意,我不使用UPDATE此值,因为它不似乎必要的(你可以提供更多信息这可以解释为什么它是).

相反,对于每一行table1,这将搜索table1具有相同值的行column1.如果一个找到,INSERT被执行.如果找到一个IS,则执行更新.


你的一直在做的是说如果(a.column3 = 'UPDATE')找到一个匹配.这意味着每一行都table2与每一'UPDATE'行匹配table1- 使其尝试table2使用来自行的值更新同一行table1.

然后,也a.column3 <> 'UPDATE'将插入每一行table2.