Oracle/SQL Server下使用存储过程对比同schema两表各列数据实现方案问询
存储过程实现表数据差异对比方案
前提说明
两张表的基础结构如下:
- 表1(示例命名:
salary_old)字段:dep_name(部门名称)、emp_name(员工姓名)、sal(薪资) - 表2(示例命名:
salary_new)字段:dep_name(部门名称)、emp_name(员工姓名)、sal(薪资)、status(状态)
这里默认dep_name+emp_name是两张表的唯一匹配键,用来定位同一名员工的对应记录。
实现思路
- 以唯一匹配键为关联条件,关联两张表
- 分三类差异场景识别:仅表1存在的记录、仅表2存在的记录、两边都存在但薪资不一致的记录
- 存储过程支持直接输出差异结果,同时会将差异写入结果表留存,方便后续回溯
存储过程代码(MySQL版本)
DELIMITER // CREATE PROCEDURE compare_salary_table_diff() BEGIN -- 先创建差异结果表(不存在则创建) CREATE TABLE IF NOT EXISTS salary_diff_result ( diff_type VARCHAR(50) COMMENT '差异类型', dep_name VARCHAR(100) COMMENT '部门名称', emp_name VARCHAR(100) COMMENT '员工姓名', old_sal DECIMAL(10,2) COMMENT '表1薪资', new_sal DECIMAL(10,2) COMMENT '表2薪资', new_status VARCHAR(20) COMMENT '表2状态', create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '对比时间' ); -- 清空上一次的对比结果 TRUNCATE TABLE salary_diff_result; -- 插入仅在表1存在的记录 INSERT INTO salary_diff_result (diff_type, dep_name, emp_name, old_sal) SELECT '仅旧表存在', t1.dep_name, t1.emp_name, t1.sal FROM salary_old t1 LEFT JOIN salary_new t2 ON t1.dep_name = t2.dep_name AND t1.emp_name = t2.emp_name WHERE t2.emp_name IS NULL; -- 插入仅在表2存在的记录 INSERT INTO salary_diff_result (diff_type, dep_name, emp_name, new_sal, new_status) SELECT '仅新表存在', t2.dep_name, t2.emp_name, t2.sal, t2.status FROM salary_new t2 LEFT JOIN salary_old t1 ON t1.dep_name = t2.dep_name AND t1.emp_name = t2.emp_name WHERE t1.emp_name IS NULL; -- 插入两边都存在但薪资不一致的记录 INSERT INTO salary_diff_result (diff_type, dep_name, emp_name, old_sal, new_sal, new_status) SELECT '薪资不一致', t1.dep_name, t1.emp_name, t1.sal, t2.sal, t2.status FROM salary_old t1 INNER JOIN salary_new t2 ON t1.dep_name = t2.dep_name AND t1.emp_name = t2.emp_name WHERE t1.sal <> t2.sal; -- 直接输出差异结果 SELECT * FROM salary_diff_result; END // DELIMITER ;
使用方法
直接执行存储过程即可得到全量差异结果:CALL compare_salary_table_diff();
注意事项
- 如果你的唯一匹配键不是部门+姓名,可自行修改关联条件对应的字段
- 如果使用Oracle、PostgreSQL等其他数据库,仅需要调整存储过程的声明格式、内置函数即可,核心对比逻辑完全通用
- 表数据量较大的情况下,建议给关联字段添加索引提升对比效率
内容的提问来源于stack exchange,提问作者Rahul T R
相关产品推荐
相关产品推荐

