Fix MySQL dates to Prepare for Oracle Migration
eric256
created: 2005-12-21 12:18:50

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 WHERE `$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() WHERE `$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() WHERE `$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!


___________
Eric Hodges $_='y==QAe=e?y==QG@>@?iy==QVq?f?=a@iG?=QQ=Q?9'; s/(.)/ord($1)-50/eigs;tr/6123457/- \/|\\\_\n/;print;

perlmonks.org content © perlmonks.org and eric256

prlmnks.org © 2006 edmund von der burg (eccles & toad)

v 0.03