在 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_id | emp_name | salary |
---|---|---|
1 | Alice | 5000 |
2 | Bob | 6500 |
3 | Charlie | 7000 |
解释
emp_id = 2
的 Bob 存在于employees
表,因此他的薪资被 更新 为6500
emp_id = 3
的 Charlie 在employees
表中 不存在,因此被 插入
注意事项
- ON 条件必须唯一:否则可能导致多个匹配更新错误。
WHEN MATCHED THEN UPDATE
不能更新主键:如果需要修改主键,需要先删除旧数据再插入新数据。- 可以使用
DELETE
语句:WHEN MATCHED AND e.salary > 10000 THEN DELETE
这会删除满足条件的匹配行。
这样,MERGE INTO
语句能有效地简化 INSERT
和 UPDATE
的操作,提高 SQL 语句的可读性和执行效率。