简单实验-A/B两用户下表结构比较(存储过程游标)

题目:从A/B库分别导出表结构,然后比较两者之前的区别(Oracle数据库)

思路:先对表名进行匹配,有无比较,如果都有再进行字段比较;字段也是先匹配有无,然后匹配类型长度等。

问题:①、

          遇到该问题未仔细看错误提示。到时去翻看存储过程。实际问题

         

exit when cur%notfound;   --特么这边应该是 cur%notfound    sql%notfound 这个是隐式游标里的

   ②、遍历问题  对表进行遍历 显示游标,分别处理

             对字段进行遍历(内部再循环),用的是内部for rec循环

 

for cur_b in (
        select (case when a.table_name is null then b.table_name else a.table_name end) tbname,
               (case when  a.COLUMN_NAME is null then b.COLUMN_NAME else a.COLUMN_NAME end)clname,
               a.data_type type1,
               b.data_type type2,
               a.data_length len1,
               b.data_length len2
          from (select table_name,COLUMN_NAME, data_type, data_length
                  from all_tab_cols
                 where owner = upper(cur_a.owner1)
                   and table_name = upper(cur_a.name1)) a
          full join (select table_name,COLUMN_NAME, data_type, data_length
                       from all_tab_cols
                      where owner = upper(cur_a.owner2)
                        and table_name = upper(cur_a.name2)) b --内部怎么再循环?
            on (a.COLUMN_NAME = b.COLUMN_NAME) --外关联<>有问题
) loop
 --如果不相等
   if (cur_b.type1 <> cur_b.type2 or cur_b.len1<> cur_b.len2 )then 
           insert into scott.test_ab
        (tname, cname, a_bj, b_bj, a_type, b_type, a_len, b_len)
        values
        (cur_b.tbname,cur_b.clname,1,1,cur_b.type1,cur_b.type2,cur_b.len1,cur_b.len2);
   end if;
end loop;
    end if;


解决:可以在遍历的时候对数据进行判断,也可以先存入数据,在通过特定条件删除


create or replace procedure p_test_ab2(USER_A in VARCHAR2,
                                       USER_B in VARCHAR2)
/*
  查看A用户下表结构是否一致
  createuser:dong
  cteratedate:2015.09.14 16:55
  */
 is
  --获取传入参数
  var_a varchar2(20) := user_a;
  var_b varchar2(20) := user_b;
  --定义游标  先全关联表数据
  cursor cur is
    select b.owner      owner1,
           b.table_name name1,
           c.owner      owner2,
           c.table_name name2
      from (select * from all_tables a where a.owner = upper(var_a)) b
      full join (select * from all_tables a where a.owner = upper(var_b)) c
        on (b.table_name = c.table_name);
  --定义游标变量
  cur_a     cur%rowtype;
  TAB_NAMEA varchar(30); --遍历的表名
  num_1     number; --判断条件
begin
  --创建表存放比较差错数据


  select count(1)
    into num_1
    from all_tables a
   where a.owner = 'SCOTT'
     and a.table_name = 'TEST_AB';
  if num_1 > 0 then
    execute immediate 'truncate table scott.test_ab';


  else
    execute immediate '
   create table scott.test_ab (
   tname varchar2(20) ,  --表名
   cname varchar2(30), --列明
   a_bj  char(1),  --是否a中存在
   b_bj  char(2),  --是否b中存在
   a_type varchar2(30), --字段类型a
   b_type varchar2(30), --字段类型b
   a_len   number ,    --字段长度a
   b_len   number     --字段长度b
   )
   ';


  end if;
  --比较列信息
  --按表遍历


  open cur;


  loop
    fetch cur
      into cur_a;
    exit when cur%notfound; --特么这边是 cur%notfound    sql%notfound 这个是隐式游标里的
    /*    dbms_output.put_line(cur_a.table_name);*/


    --如果A中不存在
    if cur_a.name1 is null then
      insert into scott.test_ab
        (tname, cname, a_bj, b_bj, a_type, b_type, a_len, b_len)
        select a.owner,
               a.table_name,
               0,
               1,
               null,
               a.data_type,
               null,
               a.data_length
          from all_tab_cols a
         where a.owner = upper(cur_a.owner2)
           and a.table_name = upper(cur_a.name2);


      --如果B中不存在
    elsif cur_a.name2 is null then
      insert into scott.test_ab
        (tname, cname, a_bj, b_bj, a_type, b_type, a_len, b_len)
        select a.owner,
               a.table_name,
               1,
               0,
               a.data_type,
               null,
               a.data_length,
               null
          from all_tab_cols a
         where a.owner = upper(cur_a.owner1)
           and a.table_name = upper(cur_a.name1);


      --如果都存在
    else 
      --内部游标遍历
  for cur_b in (
        select (case when a.table_name is null then b.table_name else a.table_name end) tbname,
               (case when  a.COLUMN_NAME is null then b.COLUMN_NAME else a.COLUMN_NAME end)clname,
               a.data_type type1,
               b.data_type type2,
               a.data_length len1,
               b.data_length len2
          from (select table_name,COLUMN_NAME, data_type, data_length
                  from all_tab_cols
                 where owner = upper(cur_a.owner1)
                   and table_name = upper(cur_a.name1)) a
          full join (select table_name,COLUMN_NAME, data_type, data_length
                       from all_tab_cols
                      where owner = upper(cur_a.owner2)
                        and table_name = upper(cur_a.name2)) b --内部怎么再循环?
            on (a.COLUMN_NAME = b.COLUMN_NAME) --外关联<>有问题
) loop
 --如果不相等
   if (cur_b.type1 <> cur_b.type2 or cur_b.len1<> cur_b.len2 )then 
           insert into scott.test_ab
        (tname, cname, a_bj, b_bj, a_type, b_type, a_len, b_len)
        values
        (cur_b.tbname,cur_b.clname,1,1,cur_b.type1,cur_b.type2,cur_b.len1,cur_b.len2);
   end if;
end loop;
    end if;


    --先插入再删除


  end loop;
commit;
  close cur;
exception
  when others then
    dbms_output.put_line(Sqlcode || '    ' || substr(sqlerrm, 1, 200));
end;



--调用
declare 
 p_test_ab2('app','apps');
end;


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值