暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 比较来自不同架构的两个相同表,不带主键且列数不相同

ASKTOM 2019-12-18
612

问题描述

我们在两个不同的模式中有表 “客户”。两者都没有任何主键,并且两个表中的列编号不匹配 (即schema1表可以有97列其他schema表101)。两个表中存在的列名相同。我的任务是比较这两个表。

首先,为此,我创建了函数,该函数将在两个表中获取公共列。

create or replace function getcolumn(scheam1 varchar2,table1 varchar2) return sys_refcursor
as lc_refcursor
begin open lc_refcursor for 
select c1.column_name from sys.all_tab_columns c1 inner join user_tab_columns c2 on c1.column_name=c2.column_name and c1.table_name=c2.table_name where c1.owner=scheam1 and c1.table_name=table1 ;
return lc_refcursor; 
end;
复制


然后我会把这个调用到一个过程中,使用这个列列表我们可以比较两个表。(我希望算法是正确的,如果不是,请建议算法比较表)

create or replace procedure comparetable( schema1 in varchar2,table1 in varchar2,schema2 in varchar2,table2 in varchar2, p_array_size in number default 100 )
 as l_cursor sys_refcursor; 
l_owner dbms_sql.varchar2_table;
l_object_name dbms_sql.varchar2_table; 
l_object_id dbms_sql.number_table;
l_created dbms_sql.date_table;
l_processed_cnt number := 0;
column_list varchar2(3000);begin
column_list := 'select * from getcolumn('||schema1||','||table1||'))';

 open l_cursor for 'select t1.* from (select distinct'||column_list||'from'||table1||')t1 where not exists(select 1 from'||schema2||'.'||table2||'t2 where (t1.'||column_list||'=t2.'||column_list||'or t1.||column_list||'is null and t2.'||column_list|| is null))';
 loop
 fetch l_cursor BULK COLLECT
 into l_owner, l_object_name, l_object_id, l_created
 LIMIT p_array_size;
 for i in 1 .. l_owner.count
 loop
 l_processed_cnt := l_processed_cnt+1;
 end loop;
 exit when l_cursor%notfound;
 end loop;
 close l_cursor;
 dbms_output.put_line( 'processed ' || l_processed_cnt || ' records' );
 end;
复制


此过程在第13行给出错误为缺少表达式。

请帮助解决错误以及根据记录加载日期比较表的算法 (我还没有通过此输入)。

专家解答

首先:

你正在使用字符串连接。所以SQL注入是一种风险。确保您验证了这些值!

接下来:

column_list := 'select * from getcolumn('||schema1||','||table1||'))';
复制


Getcolumn返回一个refcursor。您不能在查询的from子句中使用它。您必须将其更改为表函数。

或者做这样的事情:

create table t1 (
  c1 int,
  c2 int,
  c3 int
);
create table t2 (
  c2 int,
  c3 int,
  c4 int
);

with cols as ( 
  select column_name from user_tab_cols
  where  table_name = 'T1'
  intersect 
  select column_name from user_tab_cols
  where  table_name = 'T2'
)
  select listagg ( column_name, ',' ) 
           within group ( order by column_name )
  from   cols;

LISTAGG(COLUMN_NAME,',')WITHINGROUP(ORDERBYCOLUMN_NAME)   
C2,C3 
复制


并将结果包含在您的列比较中。

最后:

比较只返回T1中没有t2匹配的行。T2中的行而不是T1中的行呢?你也需要这些吗?

还有这个:

t1.'||column_list||'=t2.'||column_list
复制


没用的。您需要单独比较每一列。

在比较表中检查这些答案以获取其他方法:

https://asktom.oracle.com/pls/apex/asktom.search?tag=how-to-compare-two-tables-of-data
https://asktom.oracle.com/pls/apex/f%3Fp%3D100:11:0::::P11_QUESTION_ID:1004115105172
文章转载自ASKTOM,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论