在工作中需要完成这么一个需求:比较两个表的表结构是否形相同,并找出差异.比较两个表中的数据是否相同,并找出差异数据?
    分析:由于表结构中字段比较多,手工比较很浪费时间,而且不能保证不出错误.对于表中的数据那就能多了,更不能靠这种方式比较.

为了思考问题简单和方便测试,首先先建立两个测试表,并插入一些测试数据吧,sql如下:

  1. create table t_A
  2. (
  3. id   VARCHAR2(36) not null,
  4. name VARCHAR2(100),
  5. age  NUMBER,
  6. sex  VARCHAR2(2)
  7. );
  8. insert into t_A (id, name, age, sex)
  9. values ('1', '1', 1, '1');
  10. insert into t_A (id, name, age, sex)
  11. values ('2', '2', 2, '2');
  12. commit;
  13. create table t_B
  14. (
  15. id    VARCHAR2(36) not null,
  16. name  VARCHAR2(100),
  17. age   NUMBER,
  18. clazz VARCHAR2(36)
  19. );
  20. insert into t_B (id, name, age, clazz)
  21. values ('1', '1', 1, '1');
  22. insert into t_B (id, name, age, clazz)
  23. values ('2', '2', 1, '3');
  24. insert into t_B (id, name, age, clazz)
  25. values ('3', '3', 3, '3');
  26. commit;
create table t_A
(
id VARCHAR2(36) not null,
name VARCHAR2(100),
age NUMBER,
sex VARCHAR2(2)
); insert into t_A (id, name, age, sex)
values ('1', '1', 1, '1');
insert into t_A (id, name, age, sex)
values ('2', '2', 2, '2');
commit; create table t_B
(
id VARCHAR2(36) not null,
name VARCHAR2(100),
age NUMBER,
clazz VARCHAR2(36)
); insert into t_B (id, name, age, clazz)
values ('1', '1', 1, '1');
insert into t_B (id, name, age, clazz)
values ('2', '2', 1, '3');
insert into t_B (id, name, age, clazz)
values ('3', '3', 3, '3');
commit;

解决过程:刚开始考虑使用存储过程,用循环比较的方式处理,首先需要找出能得到表结构的sql,查阅资料得知,在Oracle中所有表结构信息都存储在user_tab_columns中,那么查询单个表的表结构信息很简单: select column_name from user_tab_columns where table_name = 't_A'; 运行后发现查不到结果,为什么呢?去掉查询条件后能查询出结果,核对后发现原来在user_tab_columns中存储的内容都是大写的,原来如此,sql改为如下就可以查询出结果了: select column_name from user_tab_columns where table_name = 'T_A'; 写这样一个存储过程发现还是有点复杂的,网上找找有没有现成的,自己写了一会发现很复杂.网上找的时候找到了一个minus关键字.科普一下:在oracle中union 并集 intersect 交集  minus 差集;我可以用差集来实现那个需求吗? 很快就写出了sql:

  1. /*1.比较表结构 */
  2. (select column_name
  3. from user_tab_columns
  4. where table_name = 'T_A'
  5. minus
  6. select column_name
  7. from user_tab_columns
  8. where table_name = 'T_B')
  9. union
  10. (select column_name
  11. from user_tab_columns
  12. where table_name = 'T_B'
  13. minus
  14. select column_name
  15. from user_tab_columns
  16. where table_name = 'T_A');
  17. /* 2.比较表数据 */
  18. (select *
  19. from t_A
  20. minus
  21. select * from t_B)
  22. union
  23. (select *
  24. from t_B
  25. minus
  26. select * from t_A)
/*1.比较表结构 */
(select column_name
from user_tab_columns
where table_name = 'T_A'
minus
select column_name
from user_tab_columns
where table_name = 'T_B')
union
(select column_name
from user_tab_columns
where table_name = 'T_B'
minus
select column_name
from user_tab_columns
where table_name = 'T_A'); /* 2.比较表数据 */
(select *
from t_A
minus
select * from t_B)
union
(select *
from t_B
minus
select * from t_A)

看看sql的运行效果吧:

表t_A结构及数据:

表t_B结构及数据:

表结构差异:

数据差异:

反思:为什么我之前没想到用差集呢? 1.数学没有学好,没有数学的思维.并集交集和差集的概念早就在中学学过,但数学思维没有建立,所以....得补补数学啦~ 2.oracle函数不熟,看来我需要找一本oracle函数手册,没事的时候就翻翻.

oracle中比较两表表结构差异和数据差异的方法的更多相关文章

  1. 转-oracle中比较两表表结构差异和数据差异的方法

    oracle中比较两表表结构差异和数据差异的方法 原作者:li2008xue2008ling  出处:http://blog.csdn.net       在工作中需要完成这么一个需求:比较两个表的表 ...

  2. 在Oracle中计算两个日期间隔的天数、月数和年数

    一.天数: 在Oracle中,两个日期直接相减,便可以得到天数: select to_date('08/06/2015','mm/dd/yyyy')-to_date('07/01/2015','mm/ ...

  3. oracle中计算两个日期的相差天数、月数、年数、小时数、分钟数、秒数等

    oracle如何计算两个日期的相差天数.月数.年数.小时数.分钟数.秒数 1.相差天数(两个日期相减) --Oracle中两个日期相差天数-- select TO_NUMBER(TO_DATE('20 ...

  4. 恢复oracle中误删除drop掉的表 闪回的方法

    恢复oracle中误删除drop掉的表   查看回收站中表 --需要在其所在用户下查询 回收站对象 select object_name,original_name,partition_name,ty ...

  5. oracle中查找和删除重复记录的几种方法总结

    平时工作中可能会遇到当试图对库表中的某一列或几列创建唯一索引时,系统提示 ORA-01452 :不能创建唯一索引,发现重复记录. 下面总结一下几种查找和删除重复记录的方法(以表CZ为例): 表CZ的结 ...

  6. C#以及Oracle中的上取整、下取整方法

    1.C#中: 上取整——Math.Ceiling(Double),即返回大于或等于指定双精度浮点数的最大整数(也可称为取天板值): eg:  Math.Ceiling(1.01)=2;      Ma ...

  7. 使用Servlet根据浏览器request的get方法获取值,将磁盘中与之对应的json数据删除的方法

    package com.swift; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStrea ...

  8. Oracle中保留两位小数

    在最近的项目开发中,有个业务需求是界面显示的数字需要保留两位小数,目前我想到的解决方法有两种: (1)在写SQL的时候,直接保留两位小数 (2)在java代码里面将查询出来的数进行格式化处理,保留两位 ...

  9. oracle中时间戳转为Date类型的数据

    问题描述: 一个表中原本应该存放date类型的数据,但是不知道之前哪位大仙把两个字段的类型建成了NUMBER类型的了,这样在后台看时间肯定不方便.现在需要改成date类型,但是现在库中是有数据的,不能 ...

随机推荐

  1. <%%>与<scriptrunat=server>,<%=%>与<%#%>的区别

      这些东西都是asp.net前台页面与后台代码交互过程中经常使用的,它们之间有的非常相似,又有一些不同.对比学习下,看看他们之间的联系与区别. 首先看<%%>与<scriptrun ...

  2. PPTP + FreeRADIUS + MySQL 安装与配置

    原文地址:http://www.zhukun.net/archives/5375 PPTP + FreeRADIUS + MySQL 安装与配置 2012/03/29Linux运维centos.Fre ...

  3. MEF 编程指南(十二):批量组合

    MEF 容器实例并非不可变的.如果目录支持改变(像监控目录变动)或者在运行时添加/移除部件都可能发生改变.以前,你不得不做出改动并且调用 CompositionContainer 上的 Compose ...

  4. ios 7.1 7.1.1 半完美越狱后 电脑訪问手机越狱文件夹的方法

    7.1和7.1.1因为越狱不成熟,半完美越狱后电脑上无法訪问系统越狱文件夹,如var usr 等等. 今天有些意外地发现,能够在电脑上使用手机的越狱文件夹我手机 i4 7.1.1 联通 半完美越狱,没 ...

  5. HDU 5510 Bazinga 暴力匹配加剪枝

    Bazinga Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5510 ...

  6. 【每日一摩斯】-Index Skip Scan Feature (212391.1)

    INDEX Skip Scan,也就是索引快速扫描,一般是指谓词中不带复合索引第一列,但扫描索引块要快于扫描表的数据块,此时CBO会选择INDEX SS的方式. 官方讲的,这个概念也好理解,如果将复合 ...

  7. git 提交远程

    一.从远程克隆项目,修改后提交 1.先切换要放项目的本地目录 C:\Users\chendd>cd E:\web C:\Users\chendd>e: 2.根据服务器的git地址克隆到本地 ...

  8. iOS利用单例实现不同界面间的数据传输

    首先写一个单例类,继承NSObject check.h文件中 @property(strong ,nonatomic) UITable * Table; @property(strong ,nonit ...

  9. 动态缓存技术之CSI,SSI,ESI

    平常我们谈到网络缓存技术,大多是以页面为单位的,比如,新闻网站中将执行后的结果,缓存为一个静态html文件,下次访问时就直接访问这个静态页面了! 减轻了服务器压力!但是,如果一个页面大部分是可静态的, ...

  10. jQuery的动画效果

    jQuery 是一个 JavaScript 库.jQuery 库可以通过一行简单的标记被添加到网页中. <script type="text/javascript" src= ...