在 Oracle 中,MERGE INTO 语句用于合并数据,它可以根据匹配条件决定是否更新已存在的记录或插入新的记录,常用于数据同步和增量更新的场景。

MERGE INTO 语法

MERGE INTO target_table t
USING source_table s
ON (t.matching_column = s.matching_column)
WHEN MATCHED THEN
    UPDATE SET t.column1 = s.column1, 
               t.column2 = s.column2
WHEN NOT MATCHED THEN
    INSERT (column1, column2, column3)
    VALUES (s.column1, s.column2, s.column3);

示例

假设我们有一个 employees 表(目标表)和一个 employees_staging 表(临时表),我们要:

  • 更新 employees 表中已存在的员工信息
  • 插入 employees_staging 中不存在于 employees 表的新员工

示例数据

CREATE TABLE employees (
    emp_id NUMBER PRIMARY KEY,
    emp_name VARCHAR2(100),
    salary NUMBER
);

CREATE TABLE employees_staging (
    emp_id NUMBER PRIMARY KEY,
    emp_name VARCHAR2(100),
    salary NUMBER
);

INSERT INTO employees VALUES (1, 'Alice', 5000);
INSERT INTO employees VALUES (2, 'Bob', 6000);

INSERT INTO employees_staging VALUES (2, 'Bob', 6500);  -- Bob 的薪资有变化
INSERT INTO employees_staging VALUES (3, 'Charlie', 7000);  -- Charlie 是新员工

使用 MERGE 进行合并

MERGE INTO employees e
USING employees_staging es
ON (e.emp_id = es.emp_id)
WHEN MATCHED THEN
    UPDATE SET e.emp_name = es.emp_name,
               e.salary = es.salary
WHEN NOT MATCHED THEN
    INSERT (emp_id, emp_name, salary)
    VALUES (es.emp_id, es.emp_name, es.salary);

执行后的结果

SELECT * FROM employees;
emp_idemp_namesalary
1Alice5000
2Bob6500
3Charlie7000

解释

  • emp_id = 2 的 Bob 存在于 employees 表,因此他的薪资被 更新6500
  • emp_id = 3 的 Charlie 在 employees 表中 不存在,因此被 插入

注意事项

  1. ON 条件必须唯一:否则可能导致多个匹配更新错误。
  2. WHEN MATCHED THEN UPDATE 不能更新主键:如果需要修改主键,需要先删除旧数据再插入新数据。
  3. 可以使用 DELETE 语句WHEN MATCHED AND e.salary > 10000 THEN DELETE 这会删除满足条件的匹配行。

这样,MERGE INTO 语句能有效地简化 INSERTUPDATE 的操作,提高 SQL 语句的可读性和执行效率。