在历史跟踪或迁移测试中经常使用几乎完全相同的表,在处理这些表时一个常见的任务是将表进行对比并报告或处理不同的记录。在类 UNIX 环境中,有一个用于比较文件的 diff 命令,在 Windows 中,有一个 FC 命令。如果传入两个文件的名称,它将会显示要添加或删除哪些行才能使文件完全相同。
在 Oracle 数据库中,没有标准的类 diff 的命令(虽然有很多非 Oracle 工具可以在数据库之外完成这一任务)。其实在 SQL 中有一些方法可以用来进行类 diff 的对比,但是这里有一个最简单的方法,也有一个(对于非标准数据的)比较好的方法。
首先,我们将创建示范这一功能所需的测试数据。我们还同时创建第二个完全相同的表,第二个表比第一个表少了一行记录,又添加了一行记录。
create table emp2 as select * from emp;
delete from emp2 where empno = 7499;
insert into emp2 values (7777,'STEPHENS','WRITER',7369,sysdate,100,null,10);
简单的方法是使用 SQL 集合操作:MINUS、INTERSECT 和 UNION。MINUS 返回第一个查询中出现而第二个查询中没有出现的记录;INTERSECT 返回两个查询中都出现的记录;UNION 返回两个查询的记录。
这个例子中使用的方法与 diff 稍微有点相似,我们使用 < 字符指出只出现第一个表中的记录,使用 > 字符指出只出现第二个表中的记录,使用等号(=)指出两个表中都出现的记录。下面是显示两个表的不同之处的一个简单方法:
select
'<',t.* from (select * from emp minus select *
from emp2) t
union select '=',t.* from (select * from emp
intersect select * from emp2) t
union select '>',t.* from (select * from emp2 minus select * from emp) t;
' EMPNO
ENAME JOB MGR
HIREDATE SAL COMM DEPTNO
- -----
----------
---------
----- ---------
----- ----- ------
< 7499
ALLEN SALESMAN 7698
20-FEB-81 1600 300
30
= 7369
SMITH CLERK
7902 17-DEC-80 800 20
= 7521
WARD SALESMAN 7698
22-FEB-81 1250
500 30
= 7566
JONES MANAGER 7839
02-APR-81 2975 20
= 7654
MARTIN SALESMAN 7698
28-SEP-81 1250 1400
30
= 7698
BLAKE MANAGER 7839
01-MAY-81 2850 30
= 7782
CLARK MANAGER 7839
09-JUN-81 2450 10
= 7788
SCOTT ANALYST
7566
19-APR-87 3000 20
= 7839
KING PRESIDENT 17-NOV-81 5000
10
= 7844
TURNER SALESMAN 7698
08-SEP-81 1500 0
30
= 7876
ADAMS CLERK
7788
23-MAY-87 1100 20
= 7900
JAMES CLERK
7698
03-DEC-81 30
= 7902
FORD ANALYST 7566
03-DEC-81 3000 20
= 7934
MILLER CLERK
7782
23-JAN-82 1300 10
> 7777
STEPHENS WRITER 7369
29-JUL-04 100 10
用户评论