The title sucks but its the best I could think of. I have three scripts (that should probably be one, but I worked on and debugged them individualy so this is how they are. ;) They could certainly be coded better but here is a start in case anyone else out there is going through the agony of a migration from Oracle to MySQL.All DB connections will need to setup for your connection settings.
The first script updates empty date/datetime fields to NULL.
use strict; use warnings; use DBI; use Data::Dumper; my $dbh = DBI->connect() or die DBI->errstr; my $tables = [@ARGV]; $tables =$dbh->selectcol_arrayref("show tables;") unless defined @$ +tables; for my $table (@$tables) { print "Checking $table ... "; my $cols = $dbh->selectall_arrayref("describe $table",{Slice=>{}}) +; my @dates = grep { $_->{Type} =~ /date/ } @$cols; # print Dumper(@dates); for my $col (@dates) { my $field = $col->{Field}; my $count = $dbh->do("UPDATE `$table` SET `$field` = NULL WHER +E `$field` = '0000-00-00';"); print "fixed '$field' ($count) ... "; } print " done.\n"; # die; }
The second updates timestamp fields to the current time. This is because clients don't seem to like 0 in the timestamps and updateing to NOW() seemed safe.
use strict; use warnings; use DBI; use Data::Dumper; my $dbh = DBI->connect() or die DBI->errstr; my $tables = [@ARGV]; $tables =$dbh->selectcol_arrayref("show tables;") unless defined @$ +tables; for my $table (@$tables) { print "Checking $table ... "; my $cols = $dbh->selectall_arrayref("describe $table",{Slice=>{}}) +; my @dates = grep { $_->{Type} =~ /timestamp/ } @$cols; # print Dumper(@dates); for my $col (@dates) { my $field = $col->{Field}; my $count = $dbh->do("UPDATE `$table` SET `$field` = NOW() WHE +RE `$field` = '0000-00-00 00:00:00';"); print "fixed '$field' ($count) ... " if $count > 0; } print " done.\n"; # die; }
And the third the script checks all date/datetime fields and finds records with a day >28. It then makes sure that it is a valid date, and sets it to NULL if it is not.
use strict; use warnings; use DBI; use Data::Dumper; my $dbh = DBI->connect() or die DBI->errstr; my $tables = [@ARGV]; $tables =$dbh->selectcol_arrayref("show tables;") unless defined @$ +tables; for my $table (@$tables) { print "Checking $table ... "; my $cols = $dbh->selectall_arrayref("describe $table",{Slice=>{}}) +; my @dates = grep { $_->{Type} =~ /timestamp/ } @$cols; # print Dumper(@dates); for my $col (@dates) { my $field = $col->{Field}; my $count = $dbh->do("UPDATE `$table` SET `$field` = NOW() WHE +RE `$field` = '0000-00-00 00:00:00';"); print "fixed '$field' ($count) ... " if $count > 0; } print " done.\n"; # die; }
These are all noisy scripts that output a bit of info that is nice if you are fighting your way through thousands of migration errors like I was. The scripts automaticaly scan every colum in every table, it is not fast but it does work. I know they could fairly easily be combined into one script but they each server a specific use so I left them alone. BTW you can call any one of them with a list of tables you want it to run on if you are focused on a specific set of tables.
Hopefully this will save someone else all the trouble i went through discovering these issues. Enjoy!
|
|---|