@@ -136,7 +136,7 @@ create or replace type body ut_data_value_refcursor as
136136 end;
137137
138138 overriding member function diff( a_other ut_data_value, a_exclude_xpath varchar2, a_include_xpath varchar2 ) return varchar2 is
139- c_max_rows constant integer := 50 ;
139+ c_max_rows constant integer := 20 ;
140140 c_pad_depth constant integer := 5;
141141 l_results ut_utils.t_clob_tab;
142142 l_result clob;
@@ -145,6 +145,7 @@ create or replace type body ut_data_value_refcursor as
145145 l_diff_row_count integer;
146146 l_other ut_data_value_refcursor;
147147 l_diff_id raw(16);
148+ l_column_filter varchar2(32767);
148149 l_sql varchar2(32767);
149150 begin
150151 if not a_other is of (ut_data_value_refcursor) then
@@ -154,19 +155,20 @@ create or replace type body ut_data_value_refcursor as
154155
155156 dbms_lob.createtemporary(l_result,true);
156157
158+ l_column_filter := ut_refcursor_helper.get_columns_filter(a_exclude_xpath, a_include_xpath);
157159 if not self.is_null and not l_other.is_null then
158160 l_sql :=
159161 'with ' ||
160162 ' self_cols as (' ||
161163 ' select r.column_value.getstringval() col, rownum rn ' ||
162- ' from ( select '||ut_refcursor_helper.get_columns_filter(a_exclude_xpath, a_include_xpath) ||
164+ ' from ( select '||l_column_filter ||
163165 ' from ( select :columns_info as item_data from dual ) ucd' ||
164166 ' ) s, ' ||
165167 ' table( xmlsequence(extract(s.item_data,''/ROW/*'')) ) r' ||
166168 ' ),'||
167169 ' other_cols as (' ||
168170 ' select r.column_value.getstringval() col, rownum rn ' ||
169- ' from ( select '||ut_refcursor_helper.get_columns_filter(a_exclude_xpath, a_include_xpath) ||
171+ ' from ( select '||l_column_filter ||
170172 ' from (select :columns_info as item_data from dual ) ucd' ||
171173 ' ) s, ' ||
172174 ' table( xmlsequence(extract(s.item_data,''/ROW/*'')) ) r' ||
@@ -195,13 +197,43 @@ create or replace type body ut_data_value_refcursor as
195197
196198 if l_diff_row_count > 0 then
197199 --return rows which were previously marked as different
198- execute immediate
199- q'[select 'Row No. '||rpad( ucd.item_no, :c_pad_depth )||' '||xmlserialize( content ucd.item_data no indent)
200- from ]' || l_ut_owner || '.ut_data_set_tmp ucd
201- where ucd.data_set_guid = :self_guid
202- and ucd.item_no in (select item_no from ' || l_ut_owner || '.ut_data_set_diff_tmp ucdc where diff_id = :diff_id)
203- and rownum <= :max_rows'
204- bulk collect into l_results using c_pad_depth, self.data_set_guid, l_diff_id, c_max_rows;
200+ l_sql :=
201+ q'[with diff_info as (select item_no from ]' || l_ut_owner || q'[.ut_data_set_diff_tmp ucdc where diff_id = :diff_guid and rownum <= :max_rows)
202+ select ind||'Row No. '||rpad( rn, :c_pad_depth)||xmlserialize(content data_item no indent) diff
203+ from (select nvl(exp.rn, act.rn) rn,
204+ xmlagg(exp.col order by exp.col_no) exp_item,
205+ xmlagg(act.col order by act.col_no) act_item
206+ from (select r.item_no as rn, rownum col_no, s.column_value col,
207+ extract(s.column_value,'/*/text()|/*/*').getclobval() col_val
208+ from (select ]'||l_column_filter||q'[, ucd.item_no
209+ from ]' || l_ut_owner || q'[.ut_data_set_tmp ucd
210+ where ucd.data_set_guid = :self_guid
211+ and ucd.item_no in (select i.item_no from diff_info i)
212+ ) r,
213+ table( xmlsequence( extract(r.item_data,'ROW/*') ) ) s
214+ ) exp
215+ full outer join (
216+ select item_no as rn, rownum col_no, s.column_value col,
217+ extract(s.column_value,'/*/text()|/*/*').getclobval() col_val
218+ from (select ]'||l_column_filter||q'[, ucd.item_no
219+ from ]' || l_ut_owner || q'[.ut_data_set_tmp ucd
220+ where ucd.data_set_guid = :other_guid
221+ and ucd.item_no in (select i.item_no from diff_info i)
222+ ) r,
223+ table( xmlsequence( extract(r.item_data,'ROW/*') ) ) s
224+ ) act
225+ on (exp.rn = act.rn and exp.col_no = act.col_no)
226+ where (exp.rn is null and act.rn is not null or exp.rn is not null and act.rn is null)
227+ or nvl(dbms_lob.compare(exp.col_val, act.col_val),1) != 0 and (exp.col_val is not null or act.col_val is not null)
228+ group by nvl(exp.rn, act.rn)
229+ )
230+ unpivot (data_item for ind in (exp_item as '-', act_item as '+'))
231+ order by rn, ind]';
232+ execute immediate l_sql
233+ bulk collect into l_results
234+ using l_diff_id, c_max_rows, c_pad_depth,
235+ a_exclude_xpath, a_include_xpath, self.data_set_guid,
236+ a_exclude_xpath, a_include_xpath, l_other.data_set_guid;
205237 ut_utils.append_to_clob(l_result,chr(10) || 'Rows: [ diff count = ' || to_char(l_diff_row_count) ||' ]' || chr(10));
206238 ut_utils.append_to_clob(l_result,l_results);
207239 end if;
0 commit comments