#!/usr/local/bin/perl use strict; use warnings; use Text::Diff; my ($file1,$file2) = @ARGV; my %set1 = create_tbl_hash($file1); my %set2 = create_tbl_hash($file2); my %unique = map {$_ => 1} (keys %set1, keys %set2); my (@changes,@missing1,@missing2); for my $key (sort keys %unique) { my $e1 = exists $set1{$key}; my $e2 = exists $set2{$key}; next if $e1 && $e2 && $set1{$key} eq $set2{$key}; if ($e1 && $e2) { push @changes, $key; } elsif ($e1) { push @missing2, $key } else { push @missing1, $key; } } if (@changes) { print "-----------------------------\n"; print "-- Changed\n"; print "-----------------------------\n"; for my $key (@changes) { my $sp1 = $set1{$key}; my $sp2 = $set2{$key}; my $diff = diff \$sp1, \$sp2, {STYLE => 'Table'}; print "-- Begin $key\n"; print $diff . "\n\n"; } } if (@missing1) { print "-----------------------------\n"; print "-- Missing from first set\n"; print "-----------------------------\n"; for my $key (@missing1) { my $sp2 = $set2{$key}; print $sp2 . "\n\n"; } } if (@missing2) { print "-----------------------------\n"; print "-- Missing from second set\n"; print "-----------------------------\n"; for my $key (@missing2) { my $sp1 = $set1{$key}; print $sp1 . "\n\n"; } } exit; sub create_tbl_hash { my ($file) = @_; my %sp_hash = (); open FH, "<$file" or die "Failed to read $file. $!\n"; my $current_sp = undef; my $buffer = ''; for my $line () { $line =~ s/[\r\n]+//g; $line =~ s/\t/ /g; next if $line =~ /^(SET QUOTED|SET ANSI)/i; if ($line =~ /^GO$/) { if ($current_sp) { $sp_hash{uc($current_sp)} .= $buffer . "\n" . "GO\n"; $current_sp = undef; $buffer = ''; next; } else { next; } } elsif ($line =~ /^CREATE TABLE .*?\[([A-Z_0-9]+)\] *\( *$/i) { $current_sp = $1; $buffer = $line; next; } elsif ($line =~ /^ALTER TABLE \[.*?\]\.\[([A-Z_0-9]+)\].* ADD *$/i) { $current_sp = $1; $buffer = $line; next; } else { $buffer .= "\n" . $line; } } close FH; return %sp_hash; } #TODO handle defaults, which are added by alter table