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

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

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

[sql] view plaincopyprint?

  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:

[sql] view plaincopyprint?

  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函数手册,没事的时候就翻翻.

时间: 2024-11-14 04:54:11

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

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

oracle中比较两表表结构差异和数据差异的方法 原作者:li2008xue2008ling 出处:http://blog.csdn.net 在工作中需要完成这么一个需求:比较两个表的表结构是否形相同,并找出差异.比较两个表中的数据是否相同,并找出差异数据? 分析:由于表结构中字段比较多,手工比较很浪费时间,而且不能保证不出错误.对于表中的数据那就能多了,更不能靠这种方式比较. 为了思考问题简单和方便测试,首先先建立两个测试表,并插入一些测试数据吧,sql如下: create table t_A

oracle中LAG()和LEAD()等分析统计函数的使用方法(统计月增长率)

LAG()和LEAD()统计函数能够在一次查询中取出同一字段的前N行的数据和后N行的值.这样的操作能够使用对同样表的表连接来实现,只是使用LAG和 LEAD有更高的效率.下面整理的LAG()和LEAD()样例: LAG(EXPRESSION,<OFFSET>,<DEFAULT>)SQL> select year,region,profit ,lag (profit,1) over (order by year)  as 51xit_exp from test; YEAR RE

SQL语句oracle中如何插入Date类型的数据

转:http://chwshuang.iteye.com/blog/933926 在开发的时候,经常要写条SQL语句将信息插入表中,插入的数据如果字段是date类型,就必须将date类型转换成字符串String类型在通过sql语句插入数据库.这是我字段唯一的方法,如果有高人请另赐教! 我的解决方法是用oracle中的to_date()方法,具体看下面的例子 Oracle中插入date数据代码 insert into news(ID,MSG,SEND_TIME,TIMER) Oracle中插入da

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

平时工作中可能会遇到当试图对库表中的某一列或几列创建唯一索引时,系统提示 ORA-01452 :不能创建唯一索引,发现重复记录. 下面总结一下几种查找和删除重复记录的方法(以表CZ为例): 表CZ的结构如下: 1 SQL> desc cz 2 Name Null? Type 3 ------------------------------------------------------------------- 4 C1 NUMBER(10) 5 C10 NUMBER(5) 6 C20 VARC

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

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

【DB笔试面试164】在Oracle中,如何彻底停止expdp数据泵进程?

真题1.如何彻底停止expdp进程? 答案:许多同事在使用expdp命令时,不小心按了CTRL+C组合键,然后又输入exit命令(或者网络中断等异常情况),导致expdp进程不存在,但Oracle数据库的会话仍存在,所以dmp文件也一直在增长.在这种情况下的处理办法如下所示: 1.检查expdp进程是否还在 ps -ef | grep expdp 若存在,则可用"kill -9 process"命令杀掉expdp的进程. 2.检查会话是否仍存在,若存在则把相关的会话杀掉(注意:先使用命

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

问题描述: 一个表中原本应该存放date类型的数据,但是不知道之前哪位大仙把两个字段的类型建成了NUMBER类型的了,这样在后台看时间肯定不方便.现在需要改成date类型,但是现在库中是有数据的,不能直接从NUMBER改为DATE.所以需要建立先创建两个DATE类型的临时字段,然后把对应字段的数据转换为Date类型的数据之后存到新字段上面,最后删除老字段,将新字段改名为老字段. 一.新建两个临时字段 ALTER TABLE CS_USER ADD (CREATEDATE1 DATE,OPERAT

oracle中统计重复几次的数据有几条

源地址:http://zhidao.baidu.com/link?url=ZgCztNzCScRI5kAqGqug1LJvf7IX311EQs6fJ0-W1kOtWaaR7MrtLoV_228Ed8Fhbk6EZQeOSfZzCDQNcBUvtq select a, count(1) from tab group by a就可以找出a有几条记录 如果要找出多余一条的重复记录select a, count(1) from tab group by a having count(1) >1

Oracle中计算两个日期时间的差

--方法1 select floor((sysdate - to_date('2006-09-01 08:00:00', 'yyyy-mm-dd hh24:mi:ss'))) as sDays from dual; --ceil(n) 取大于等于数值n的最小整数; --floor(n)取小于等于数值n的最大整数; select ceil(9.6) from dual; --->10 select floor(9.6) from dual; --->9 --方法2 select ROUND(TO