如何比较 Sybase ASE 15.7 中的两个表

问题描述 投票:0回答:1

如标题所示,我需要比较两个表来检查差异,这两个表具有相同的结构,但行数不同,列的数据差异。

sql sybase sap-ase
1个回答
0
投票

也有类似的问题。

写了这个存储过程:

/*
**Author: Martin Bartscher
**Find & give out differences between two, 'same' Tables with old and new data.
*/
create or replace proc mb_diff_old_new_table(
 @table_old varchar(255) /*table with the old data*/
 ,@table_new varchar(255) /*table with the new data*/
 ,@identifier_columns varchar(16384) /*names of the columns, that identify a data set; have to be separated by a single comma*/
 ,@columns_to_compare varchar(16384) /*names of the columns, that shall be compared; have to be separated by a single comma*/
 ,@debug bit =0
)
as begin
 /*
 **declare variables
 */
 declare @sql varchar(16384)
  ,@sql_ident_cols_on varchar(16384)
  ,@sql_comp_cols_where varchar(16384)
  ,@sql_select_out_both varchar(16384)
  ,@id_cols varchar(16384)
  ,@comp_cols varchar(16384)
  ,@cur_col varchar(255)
  ,@crlf char(2)
  ,@rows_diff_old int
  ,@rows_diff_new int
  ,@com_pos int
 /*
 **initialize variables
 */
 set @sql=null
 set @sql_ident_cols_on='on ('
 set @sql_comp_cols_where='where '
 set @sql_select_out_both='select '
 set @id_cols=@identifier_columns
 set @comp_cols=@columns_to_compare
 set @cur_col=null
 set @crlf=char(13)+char(10)
 set @rows_diff_old=0
 set @rows_diff_new=0
 set @com_pos=0
 /*
 **clean up old res-tables if proc ran before
 */
 if exists(select name from sysobjects where name='mb_diff_old') begin
  drop table mb_diff_old
 end
 if exists(select name from sysobjects where name='mb_diff_new') begin
  drop table mb_diff_new
 end
 /*
 **build 'on' clause with data set identifying columns
 */
 while len(@id_cols)>0 begin
  set @com_pos=charindex(',',@id_cols)
  if @com_pos!=0 begin
   set @cur_col=left(@id_cols,@com_pos-1)
   set @id_cols=substring(@id_cols,@com_pos+1,len(@id_cols)-@com_pos)
  end
  else begin
   set @cur_col=@id_cols
   set @id_cols=null
  end
  set @sql_ident_cols_on=@sql_ident_cols_on+'ot.'+@cur_col+'=nt.'+@cur_col+@crlf
  set @sql_select_out_both=@sql_select_out_both+'ot.'+@cur_col
  if @id_cols!=null begin
   set @sql_ident_cols_on=@sql_ident_cols_on+' and '
   set @sql_select_out_both=@sql_select_out_both+','
  end
  else begin
   set @sql_ident_cols_on=@sql_ident_cols_on+')'
   set @sql_select_out_both=@sql_select_out_both+' /*identificational columns*/'+@crlf
  end
 end
 if @debug=1 begin
  print 'on-clause: '
  print @sql_ident_cols_on
  print 'select_out_both: '
  print @sql_select_out_both
  print '----------------------------------------------------------------'
 end
 /*
 **build 'where' clause with the columns with the values to compare
 */
 while len(@comp_cols)>0 begin
  set @com_pos=charindex(',',@comp_cols)
  if @com_pos!=0 begin
   set @cur_col=left(@comp_cols,@com_pos-1)
   set @comp_cols=substring(@comp_cols,@com_pos+1,len(@comp_cols)-@com_pos)
  end
  else begin
   set @cur_col=@comp_cols
   set @comp_cols=null
  end
  set @sql_comp_cols_where=@sql_comp_cols_where+'ot.'+@cur_col+'!=nt.'+@cur_col+@crlf
  set @sql_select_out_both=@sql_select_out_both+
   ',ot.'+@cur_col+' as '+@cur_col+'_alt, nt.'+@cur_col+' as '+@cur_col+'_neu'
  if @comp_cols!=null begin
   set @sql_comp_cols_where=@sql_comp_cols_where+' or '
   set @sql_select_out_both=@sql_select_out_both+@crlf
  end
 end
 if @debug=1 begin
  print 'where-clause: '
  print @sql_comp_cols_where
  print 'select_out_both: '
  print @sql_select_out_both
  print '----------------------------------------------------------------'
 end
 /*
 **all data rows from old table, without equivalent data row in new table 
 */
 set @sql='select ot.*
  into mb_diff_old
  from '+@table_old+' ot
  left join '+@table_new+' nt
  '+@sql_ident_cols_on+'
  where nt.QUARTAL=null'
 if @debug=1 begin
  print 'all data rows from old table, without equivalent data row in new table'
  print @sql
  print '----------------------------------------------------------------'
 end
 else begin
  exec (@sql)
 end
 /*
 **all data rows from new table, without equivalent data row in old table 
 */
 set @sql= 'select nt.*
  into mb_diff_new
  from '+@table_old+' ot
  right join '+@table_new+' nt
  '+@sql_ident_cols_on+'
  where ot.QUARTAL=null'
 if @debug=1 begin
  print 'all data rows from new table, without equivalent data row in old table'
  print @sql
  print '----------------------------------------------------------------'
 end
 else begin
  exec (@sql)
 end
 /*
 **all data rows from old table, with difference to new table
 */
 set @sql='insert into mb_diff_old
  select ot.*
  from '+@table_old+' ot
  join '+@table_new+' nt
  '+@sql_ident_cols_on+'
  '+@sql_comp_cols_where
 if @debug=1 begin
  print 'all data rows from old table, with difference to new table'
  print @sql
  print '----------------------------------------------------------------'
 end
 else begin
  exec (@sql)
 end
 /*
 **all data rows from new table, with difference to old table
 */
 set @sql='insert into mb_diff_new
  select nt.*
  from '+@table_old+' ot
  join '+@table_new+' nt
  '+@sql_ident_cols_on+'
  '+@sql_comp_cols_where
 if @debug=1 begin
  print 'all data rows from new table, with difference to old table'
  print @sql
  print '----------------------------------------------------------------'
 end
 else begin
  exec (@sql)
 end
 --------------------------------output--------------------------------
 /*
 **check if differences and put them out
 */
 set @sql='select @rows_diff_old=count(*) from mb_diff_old'
 if @debug=1 begin
  print "Can't determine '@rows_diff_old', because 'mb_diff_old' won't be created in debug mode."
  print '----------------------------------------------------------------'
 end
 else begin
  exec (@sql)
 end
 /*
 **If I write this (two) statement(s) directly, the parser thinks of it as a
 **mistake, because 'mb_diff_(old/new)' isn't existing when I create the proc...
 */
 set @sql='select @rows_diff_new=count(*) from mb_diff_new'
 if @debug=1 begin
  print "Can't determine '@rows_diff_new', because 'mb_diff_new' won't be created in debug mode."
  print '----------------------------------------------------------------'
 end
 else begin
  exec (@sql)
 end
 /*
 **output only if there are differences
 */
 if @rows_diff_old!=0 or @rows_diff_new!=0 or @debug=1 begin
  /*
  **All data sets, that are only in the old results.
  */
  set @sql='select "All data sets, that are only in the old results." as "result description" 
   select ot.* 
   from mb_diff_old ot
   left join mb_diff_new nt
   '+@sql_ident_cols_on+'
   where nt.QUARTAL=null'
  if @debug=1 begin
   print 'All data sets, that are only in the old results.'
   print @sql
   print '----------------------------------------------------------------'
  end
  else begin
   exec (@sql)
  end
  /*
  **All data sets, that are only in the new results.
  */
  set @sql='select "All data sets, that are only in the new results." as "result description"
   select nt.* 
   from mb_diff_old ot
   right join mb_diff_new nt
   '+@sql_ident_cols_on+'
   where ot.QUARTAL=null'
  if @debug=1 begin
   print 'All data sets, that are only in the new results.'
   print @sql
   print '----------------------------------------------------------------'
  end
  else begin
   exec (@sql)
  end
  /*
  **All data sets, that are in both results, but differ.
  */
  set @sql='select "All data sets, that are in both results, but differ." as "result description"
  '+@sql_select_out_both+'
   from mb_diff_old ot
   join mb_diff_new nt
   '+@sql_ident_cols_on
  if @debug=1 begin
   print 'All data sets, that are in both results, but differ.'
   print @sql
   print '----------------------------------------------------------------'
  end
  else begin
   exec (@sql)
  end
 end
 /*
 **output that no differences were found
 */
 else begin
  select 'There are no differences.' as 'result description'
 end
end
© www.soinside.com 2019 - 2024. All rights reserved.