eval { $dbh->prepare( $statement, { mysql_server_prepare => 1 } ) }; if ( my $error = $@ ) { ... } #### eval { local $SIG{__WARN__} = sub {}; $dbh->prepare( $statement, { mysql_server_prepare => 1 } ) }; if ( my $error = $@ ) { ... } #### use DBI; use DBD::mysql 3.0002_1; # so we have have server-side prepares use Data::Record; use Regexp::Common; my $dbh = DBI->connect( "DBI:mysql:$database:$server", $user, $pass, { AutoCommit => 0, RaiseError => 1, } ); my $sql = <<'END_SQL'; SELECT 1; ALTER TABLET foo; END_SQL use Data::Dumper; my @errors = invalid_sql($dbh, $sql); print Dumper(\@errors); sub invalid_sql { my ( $dbh, $sql ) = @_; my @errors; foreach my $statement ( split_sql($sql) ) { next unless $statement =~ /\S/; local $SIG{__WARN__} = sub {}; # XXX Why do I need this? eval { $dbh->prepare( $statement, { mysql_server_prepare => 1 } ) }; if ( my $error = $@ ) { push @errors => [ $statement => $error ]; } } return wantarray ? @errors : \@errors; } sub split_sql { my $sql = shift; my $record = Data::Record->new( { split => ';', unless => $RE{quoted}, } ); return $record->records($sql); }