问题描述
我们在两个不同的模式中有表 “客户”。两者都没有任何主键,并且两个表中的列编号不匹配 (即schema1表可以有97列其他schema表101)。两个表中存在的列名相同。我的任务是比较这两个表。
首先,为此,我创建了函数,该函数将在两个表中获取公共列。
然后我会把这个调用到一个过程中,使用这个列列表我们可以比较两个表。(我希望算法是正确的,如果不是,请建议算法比较表)
此过程在第13行给出错误为缺少表达式。
请帮助解决错误以及根据记录加载日期比较表的算法 (我还没有通过此输入)。
首先,为此,我创建了函数,该函数将在两个表中获取公共列。
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注入是一种风险。确保您验证了这些值!
接下来:
Getcolumn返回一个refcursor。您不能在查询的from子句中使用它。您必须将其更改为表函数。
或者做这样的事情:
并将结果包含在您的列比较中。
最后:
比较只返回T1中没有t2匹配的行。T2中的行而不是T1中的行呢?你也需要这些吗?
还有这个:
没用的。您需要单独比较每一列。
在比较表中检查这些答案以获取其他方法:
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
你正在使用字符串连接。所以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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。