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

为了思考问题简单和方便测试,首先先建立两个测试表,并插入一些测试数据吧,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. 文件频繁IO能有多大的差别

    测试文件写同样大小的文件,单次记录较小和单次记录较大能有多大的性能差别. 最终写入同样大小的文件,小记录需要写入10w次,大记录需要写入1w次,看下最终的性能报告

  2. django控制admin的model显示列表

    class goods(models.Model):    name = models.CharField(max_length=300)    price = models.IntegerField ...

  3. window.parent != window 解决界面嵌套问题

    页面在被嵌套的时,效果:,,如果用户点击“刷新”,该问题即可解决. 如果想通过代码解决的话,这个问题属于客户端的问题,不是服务器端的问题. 如果直接写:window.location.href = “ ...

  4. 汇编语言(学习笔记----寄存器CPU互作原理)

    一.段寄存器 1.段寄存器就是提供段地址的,8086CPU有4个段寄存器:CS(代码段寄存器),DS(数据段寄存器),SS(堆栈段寄存器),ES(附加段寄存器) 2.当8086CPU要访问内存时,由这 ...

  5. xxx-servlet.xml vs applicationContext.xml

    Spring lets you define multiple contexts in a parent-child hierarchy. The applicationContext.xml def ...

  6. C#调用WORD处理的实例代码(包含excel)

    最近程序人生(http://www.manong123.com)一个朋友让我帮他做一个小功能,其实就是把WORD文档里的内容存到数据库里去,可以实现搜索并转EXCEL的功能,需求很简单,想不到加上部署 ...

  7. S5PV210开发系列四_uCGUI的移植

    S5PV210开发系列四 uCGUI的移植 象棋小子          1048272975 GUI(图形用户界面)极大地方便了非专业用户的使用,用户无需记忆大量的命令,取而代之的是能够通过窗体.菜单 ...

  8. Android 滑动效果高级篇(七)—— 华丽翻页效果

    By 何明桂(http://blog.csdn.net/hmg25) 转载请注明出处 之前看到像ipad上的ibook的模拟书籍翻页的特效感觉很炫,在android上也有像laputa和ireader ...

  9. StarlingMVC Framework中文教程

    配置与开始 将Starling项目配置为StarlingMVC项目,仅需几行代码.在继承于starling.display.Sprite的起始类里,创建一个StarlingMVC的实例,并传递给它三个 ...

  10. javascript常用方法整理--数组篇

    1. arrayObject.slice(start,end) 从已有的数组中返回选定的元素 参数 描述 start 必需.规定从何处开始选取.如果是负数,那么它规定从数组尾部开始算起的位置.也就是说 ...