in reply to error catching

Don't use $! for catching SQL exceptions. Use DBI::errstr or $dbh->errstr;
Connect DB with RaiseError=>1 .
ie.,
my $dbh = DBI->connect($dbn,$dbu,$dbp, {RaiseError=>1}) or die "can't connect $dbn,$dbu,_ connect error $DBI::errstr" ;
Catch the exception using,
$sth=$dbh->prepare($query) or die("Error while preparing $query".$DBI::errstr);
$sth->execute() or die("Error while executing $query". $DBI::errstr);