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

为了思考问题简单和方便测试,首先先建立两个测试表,并插入一些测试数据吧,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. 校园网通过路由器开WiFi

    闲话少说,为了在一个宿舍内达到一个网口N人上网目的,特地写一篇关于校园网通过路由器开wifi的文章,希望能帮助同学把wifi开起来,请看正文(操作以下步骤前建议先重置路由,也就是初始化复位): 一.一 ...

  2. 使用 EPPlus,NPOI,操作EXCEL

    NPOI,       读取xls文件(Excel2003及之前的版本)   (NPOI.dll+Ionic.Zip.dll)     http://npoi.codeplex.com/ EPPlus ...

  3. 配置 Spring 的声明式事务

    <!-- 1. 配置事务管理器 --> <bean id="transactionManager" class="org.springframework ...

  4. [Javascript] Monads

    Monads allow you to nest computations. They are a pointed functor that adds mjoin and chain function ...

  5. oc-11-结构体

    #import <Foundation/Foundation.h> /* 设计一个“学生”类 1)属性 姓名 生日 用结构体作为类的实例变量(生日) 定义结构用来描述 生日 类名: Stu ...

  6. MySQL · 特性分析 · MDL 实现分析

    http://mysql.taobao.org/monthly/2015/11/04/ 前言 在MySQL中,DDL是不属于事务范畴的,如果事务和DDL并行执行,操作相关联的表的话,会出现各种意想不到 ...

  7. MySQL 5.7: Enhanced Multi-threaded slaves

    http://geek.rohitkalhans.com/2013/09/enhancedMTS-deepdive.html   科学上网 Introduction Re-applying binar ...

  8. 如何通过VIM把代码格式化后生成HTML网页代码

    本文转自http://wangxiaoyu.blog.51cto.com/922065/203471 需求及思路:演示需要,需要网站上嵌入一些代码,我的建议做法是根据代码文件,生成相应的HTML代码, ...

  9. 今天再分享一个TextView内容风格化的类

    /* * Copyright (C) 2014 Jason Fang ( ijasonfang@gmail.com ) * * Licensed under the Apache License, V ...

  10. linux后端运行(二)

    在用管理员执行一个命令后,用Ctrl+Z把命令转移到了后台.导致无法退出root的. 输入命令:exit终端显示:There are stopped jobs. 解决方法:方法一.输入命令:jobs终 ...