MERGE中的条件DELETE / INSERT / UPDATE

时间:2016-04-22 16:18:27

标签: oracle oracle11g merge oracle10g dml

我遇到了两个关于带有条件DML的MERGE的例子

First example

MERGE INTO bonuses D
   USING (SELECT employee_id, salary, department_id FROM employees
   WHERE department_id = 80) S
   ON (D.employee_id = S.employee_id)
   WHEN MATCHED THEN UPDATE SET D.bonus = D.bonus + S.salary*.01
     DELETE WHERE (S.salary > 8000)
   WHEN NOT MATCHED THEN INSERT (D.employee_id, D.bonus)
     VALUES (S.employee_id, S.salary*.01)
     WHERE (S.salary <= 8000);

我倾向于理解在MERGE中,只修改了目标表(此处为D)。当我们在WHEN中放置DML时,它将作用于目标表D.因此,在这种情况下,条件与S有什么关系,如DELETEUPDATE条款。 WHERE什么时候开始行动?匹配后?在ON之前的源/目标上?

Another related example还有一个问题

MERGE INTO destination d
  USING source s
    ON (s.id = d.id)
  WHEN MATCHED THEN
    UPDATE SET  d.description = 'Updated',
                d.status = 10
    DELETE WHERE s.status = 10;

MERGE INTO destination d
  USING source s
    ON (s.id = d.id)
  WHEN MATCHED THEN
    UPDATE SET  d.description = 'Updated',
                d.status = 10
    DELETE WHERE d.status = 10;

我没有区分两种情况:WHERE子句中的源表与目标表。

提前致谢。

2 个答案:

答案 0 :(得分:0)

MERGE操作有两个部分:采取什么行动(某种更新,包括插入和删除) - 这始终只在目标表上;什么时候采取行动 - 必须满足什么条件才能启动更新。条件必须引用目标表中的某些内容,但它也引用源表。

在您的第一个示例中:目标表只有员工ID和bounses。您希望为每位员工增加每个奖金1%的基本工资 - 并为未完全分配奖金的员工添加bounus(当该员工没有任何行时)。因此,您不仅可以查看目标表,还必须查看存储工资的其他位置。在这种情况下,“WHEN MATCHED”确保您在两个表中查看相同的员工ID。然后你将奖金提高基本工资的1%;从源表中读取基本工资。然后,如果员工的基本工资大于80,000,则完全删除奖金(BONUS表中的员工ID不会有行) - 这必须是数据库中反映的业务决策。因此,您可以看到如何在目标表以外的位置引用数据,即使更改本身只影响目标。

在你的第二个例子中,效果是一样的。

答案 1 :(得分:0)

在第一个例子中, 1.确定属于部门80的员工。这些员工在奖金表中可能会或可能没有针对其员工ID的奖励记录。 2.如果奖金中已经存在奖金,则将该员工的奖金增加1%的工资奖励。在那之后,如果员工的工资超过8000,他就不能有奖金,所以从奖金中删除他的奖金记录。 3.如果没有奖金,如果员工工资不超过8000,请添加新的奖金记录。

在这种情况下用于理解目的的序列将是ON,匹配,然后更新,在哪里,删除,在不匹配时,在哪里,插入

在第二个例子中, 查询1:如果源记录存在于目标中, 一个。更新目的地描述和状态。 湾然后,如果源状态为10,则从目标中删除具有相同ID的记录。

查询2:如果目标中存在源记录, 一个。更新目的地描述和状态。 湾然后从目的地删除该记录。

在query2中,更新是多余的,除非有任何触发器更新其他表。

在这种情况下用于理解目的的序列将是ON,匹配时,然后更新,在哪里,删除

希望这有帮助。