簡體   English   中英

DBI - Perl - 記錄MySQL警告

[英]DBI - Perl - Logging MySQL warnings

我正在使用DBI並希望將MySQL WARNINGS的日志記錄添加到此腳本中。 我能夠毫無問題地記錄真正的MySQL錯誤,但此時我需要追蹤正在生成的MySQL警告。 如果mysql語句失敗,我可以將錯誤的sql語句打印到bad_sql.txt並自動生成一封電子郵件。 我需要做兩個更改,我真的卡住了1)如果語句執行但有一個mysql警告我想要捕獲到last_sql_warning.txt 2)如果語句failes做到鎖定超時我想重新提交最多查詢兩次。

這就是現在被轉儲到日志中的內容。

MiscLibs::MySQL::MySQLDoCmd, MySQL.pm line 564:
-->UPDATE tbl_xxx_files SET ReloadStart=123" WHERE (FileName="image.txt")<--

相關的代碼塊

#=====================================================================================
# Execute MySQL commands and handle errors
#=====================================================================================

sub MySQLDoCmd ($;$) {

my ($MySQLCmd, $Quite) = @_;

 if ( eval { $DBHandle->do($MySQLCmd) } ) {
   open (MYFILE2, '>/bb/bin/fa/logs/last_sql_warning.txt');
   # trying to write warning to log.  As a first pass I was attempting to write 
   # each statement to the log and include any warnings.  What I would like code to
   # do is check if there is a warning and only then write that statement to the log. 

   print MYFILE2 MySQLMakeID() . ": $DBHandle->errstr\n-->$MySQLCmd<--\n";

return 0;

} elsif ( ! $Quite ) {
  open (MYFILE, '>>/bb/bin/fa/logs/badsql.txt');
  print MYFILE  MySQLMakeID() . ": $@\n-->$MySQLCmd<--\n";

#=========SENDS EMAIL ON STATEMENT FAILURE===================
 while (my ($addressee, $address) = each (%emailList))
 {
     print STDERR "INFO: Sending email to $addressee at address $address\n";
     $message =~ s/ADDRESSEE/$addressee/g;
     $message =~ s/ERRORREASON/$errMessage/g;
     &sendMail($addressee, $address, $message);
     $message =~ s/$addressee/ADDRESSEE/g;
     $message =~ s/$errMessage/ERRORREASON/g;
  }

return 1;

 } else {
  return 1;

 }

}

完整的代碼塊

use strict;                        # Everything must be defined before it is used
use warnings;                      # Print warnings
use POSIX;                         # Provides POSIX functions
use English '-no_match_vars';      # Provides access to English version of builtin variables
use Net::SMTP;

#===================================================================================================

package MiscLibs::MySQL;
use Exporter ();

our ($VERSION, @ISA, @EXPORT, @EXPORT_OK);

$VERSION = '1.00';
@ISA = qw(Exporter);
@EXPORT_OK = ( );
@EXPORT = qw( 

MySQLOpenConnection
MySQLCloseConnection

MySQLCloseHandle

MySQLErrNo
MySQLError
MySQLHostInfo
MySQLInfo
MySQLInsertID
MySQLProtoInfo
MySQLServerInfo
MySQLStat
MySQLThreadID
MySQLDBDStats
MySQLAutoReconnect
MySQLUseResult
MySQLShowTables
MySQLShowColumns
MySQLValidateFields
MySQLNumOfFields
MySQLErrStr
MySQLUseResults

MySQLDoCmd

MySQLDeleteRows
MySQLDeleteRowsICS
MySQLInsertRow
MySQLUpdateRows

MySQLSelectRows
MySQLGetHashRef
MySQLGetArray
MySQLSetLastUpdate
MySQLSetReportState

MySQLTruncateTable
MySQLDisableKeys
MySQLEnableKeys
MySQLOptimizeTable

MySQLCacheAddTable
MySQLCacheAddBuffer
MySQLCacheFlush

);
#=====================================================================================
my %emailList = (
                   "bob"=>"\@bog.com",
               );

my $errMessage = "error_message";
my $message = "MySQl Query Timed out - check logs/";

#======================================================================================
 sub sendMail()
{
 #not relevant - smtp code

     print "EXECUTE: Mail sent successfully\n";
}

#======================================================================================

use File::Basename;                # Provides basename, dirname and fileparse functions
use Data::Dumper;
use DBI;                           # Interface to MySQL

my $DBHandle;

my %CacheFieldNameStrings;
my %CacheFieldNameArrays;
my %CacheSizes;
my %CacheFieldValues;
my %CacheDupKeyCmds;

my %ValidateFieldNames;

my $MaxCacheSize = 50;

1;

#=====================================================================================
# Create an ID string for error reporting
#=====================================================================================

sub MySQLMakeID {

  my ($package, $filepath, $line, $subroutine, $hasargs,
      $wantarray, $evaltext, $is_require, $hints, $bitmask) = caller(1);

  $subroutine =~ s/main:://;

  my $filename = basename($filepath);

  my $id = "$subroutine, $filename line $line";

  # print "ID: '$id'\n";

  return $id;

}

#=====================================================================================
# Open MySQL connection and get reference information
#=====================================================================================

sub MySQLOpenConnection (;$) {

  my ( $NewMaxCacheSize ) = @_;

  my $Database;
  my $Host;
  my $Port;
  my $DSN;
  my $User;
  my $Password;
  my %Options;

  if ( defined($NewMaxCacheSize) && ($NewMaxCacheSize > 1) ) { $MaxCacheSize = $NewMaxCacheSize }

  $Database = $ENV{MySQLDatabase}; if ( ! defined($Database) ) { $Database = "database" }
  $Host     = $ENV{MySQLHost};     if ( ! defined($Host)     ) { $Host     = "host" }
  $Port     = $ENV{MySQLPort};     if ( ! defined($Port)     ) { $Port     = 123 }

  $DSN = "DBI:mysql";
  $DSN = $DSN . ":$Database";
  $DSN = $DSN . ";host=$Host";
  $DSN = $DSN . ";port=$Port";
  $DSN = $DSN . ";mysql_compression=1";

  $User     = 'user';
  $Password = 'pw';

  %Options = ( RaiseError => 1 );

  $DBHandle = DBI->connect($DSN, $User, $Password, \%Options);

  return $DBHandle;

}

#=====================================================================================
# Close MySQL connection opened above or a handle that is passed
#=====================================================================================

sub MySQLCloseConnection {
  if ( $DBHandle ) { $DBHandle->disconnect }
  return 0;
}

sub MySQLCloseHandle ($) { 
  my ($sh) = @_;
  if ( $sh ) { $sh->finish() }
  return 0;
}

#=====================================================================================
# Return a various database handle values and conditions
#=====================================================================================

sub MySQLErrNo      () { return $DBHandle->{'mysql_errno'}      }
sub MySQLError      () { return $DBHandle->{'mysql_error'}      }
sub MySQLHostInfo   () { return $DBHandle->{'mysql_hostinfo'}   }
sub MySQLInfo       () { return $DBHandle->{'mysql_info'}       }
sub MySQLInsertID   () { return $DBHandle->{'mysql_insertid'}   }
sub MySQLProtoInfo  () { return $DBHandle->{'mysql_protoinfo'}  }
sub MySQLServerInfo () { return $DBHandle->{'mysql_serverinfo'} }
sub MySQLStat       () { return $DBHandle->{'mysql_stat'}       }
sub MySQLThreadID   () { return $DBHandle->{'mysql_thread_id'}  }
sub MySQLDBDStats   () { return $DBHandle->{'mysql_dbd_stats'}  }

#=====================================================================================
# Optionally set but always return various database handle values and conditions
#=====================================================================================

sub MySQLAutoReconnect (;$) { 
  my $val = $_[0];
  if ( defined($val) ) { $DBHandle->{'mysql_auto_reconnect'} = $val }
  return $DBHandle->{'mysql_auto_reconnect'};
}

sub MySQLUseResult (;$) { 
  my $val = $_[0];
  if ( defined($val) ) { $DBHandle->{'mysql_use_result'} = $val }
  return $DBHandle->{'mysql_use_result'};
}

#=====================================================================================
# Execute MySQL commands and handle errors
#=====================================================================================

sub MySQLDoCmd ($;$) {

  my ($MySQLCmd, $Quite) = @_;

  if ( eval { $DBHandle->do($MySQLCmd) } ) {
       open (MYFILE2, '>>/bb/bin/fa/logs/last_sql.txt');
       #!!!!! trying to write warning to log 
       print MYFILE2 MySQLMakeID() . ": $DBHandle->errstr\n-->$MySQLCmd<--\n";
      return 0;

  } elsif ( ! $Quite ) {
      open (MYFILE, '>>/bb/bin/fa/logs/badsql.txt');
      print MYFILE  MySQLMakeID() . ": $@\n-->$MySQLCmd<--\n";

#=========SENDS EMAIL ON STATEMENT FAILURE===================    
 while (my ($addressee, $address) = each (%emailList))
     {
         print STDERR "INFO: Sending email to $addressee at address $address\n";
         $message =~ s/ADDRESSEE/$addressee/g;
         $message =~ s/ERRORREASON/$errMessage/g;
         &sendMail($addressee, $address, $message);
         $message =~ s/$addressee/ADDRESSEE/g;
         $message =~ s/$errMessage/ERRORREASON/g;
      }

    return 1;

  } else {
    return 1;

  }

}

#=====================================================================================
# Delete rows from a MySQL table
#=====================================================================================

sub MySQLDeleteRows ($;$) {

  my ($Table, $WhereRef) = @_;

  my $WhereList;

  my $MySQLCmd = 'DELETE FROM ' . $Table;

  if ( $WhereRef ) {
    $WhereList = BuildLists ('where', $WhereRef);
    $MySQLCmd = $MySQLCmd . $WhereList;
  }

  return MySQLDoCmd($MySQLCmd);

}


#=====================================================================================
# Select rows from a MySQL table and return a statement handle
#=====================================================================================

sub MySQLSelectRows ($$;$$) {

  my ($What, $Table, $WhereRef, $OrderRef) = @_;

  my $MySQLCmd = "SELECT $What FROM $Table";

  if ( $WhereRef ) { $MySQLCmd = $MySQLCmd . BuildLists ('Where'  , $WhereRef) }
  if ( $OrderRef ) { $MySQLCmd = $MySQLCmd . BuildLists ('OrderBy', $OrderRef) }

  # print "MySQLSelectRows: MySQLCmd '$MySQLCmd'\n";

  my $StmtHandle;

  if ( ! eval {  $StmtHandle = $DBHandle->prepare($MySQLCmd) } ) {
    print STDERR MySQLMakeID() . ": $@\n-->$MySQLCmd<--\n";
    return undef;

  } elsif ( ! eval { $StmtHandle->execute() } ) {
    print STDERR MySQLMakeID() . ": $StmtHandle->errstr\n-->$MySQLCmd<--\n";
    return undef;

  } else {
    return $StmtHandle;

  }

}

#=====================================================================================
# Return a various statement handle values and conditions
#====================================================================================

sub MySQLNumOfFields ($) { my ($sh) = @_; return $sh->{'NUM_OF_FIELDS'}      }
sub MySQLErrStr      ($) { my ($sh) = @_; return $sh->errstr                 }

sub MySQLGetHashRef  ($) { my ($sh) = @_;
  if ( my $Ref = $sh->fetchrow_hashref() ) { return $Ref }
  else                                     { MySQLCloseHandle($sh); return undef } 
}

sub MySQLGetArray ($) { my ($sh) = @_; 
  if ( my $Ref = $sh->fetchrow_array()   ) { return $Ref }
  else                                     { MySQLCloseHandle($sh); return undef } 
}

#=====================================================================================
# Optionally set but always return various statement handle values and conditions
#=====================================================================================

sub MySQLUseResults ($;$) { 
  my ($sh, $val) = @_;
  if ( defined($val) ) { $sh->{'mysql_use_result'} = $val }
  return $sh->{'mysql_use_result'};
}

#=====================================================================================
# Update a row in a MySQL table
#=====================================================================================

sub MySQLUpdateRows ($$;$) {

  my ($Table, $SetRef, $WhereRef) = @_;

  my $MySQLCmd;
  my $SetList;
  my $WhereList;

  $MySQLCmd = 'UPDATE ' . $Table;

  $SetList = BuildLists ('set', $SetRef);

  $MySQLCmd = $MySQLCmd . $SetList;

  if ( $WhereRef ) {
    $WhereList = BuildLists ('where', $WhereRef);
    $MySQLCmd = $MySQLCmd . $WhereList ;
  }

  # print "MySQLUpdateRows: MySQLCmd '$MySQLCmd'\n";

  return MySQLDoCmd($MySQLCmd);

}



#=====================================================================================
# Truncate a MySQL table
#=====================================================================================

sub MySQLTruncateTable ($) {

  my ($Table) = @_;

  my $MySQLCmd = 'TRUNCATE TABLE ' . $Table;

  return MySQLDoCmd($MySQLCmd);

}




#=====================================================================================
#
# The routines below maintain a cache of MySQL values to allow inserting multiple
# rows at a time to improve efficiency
#
#=====================================================================================

#=====================================================================================
# Add a table to the MySQL Cache
#=====================================================================================

sub MySQLCacheAddTable ($$;$) {

  my ( $TableName, $FieldNameArray, $DupKeyCmds ) = @_;

  my $DupKeyCmd;

  my $FieldName;
  my $FieldNameString = '';

  for $FieldName ( @$FieldNameArray ) {
    if ( $FieldNameString ) { $FieldNameString = $FieldNameString . ',' }
    $FieldNameString = $FieldNameString . $FieldName;    
  }

    $CacheFieldNameStrings{$TableName} = $FieldNameString;
  @{$CacheFieldNameArrays{$TableName}} = @$FieldNameArray;
  $CacheDupKeyCmds{$TableName}         = $DupKeyCmds;
  $CacheSizes{$TableName}              = 0;
  $CacheFieldValues{$TableName}        = '';

  return 0;

}

#=====================================================================================
# Add a buffer to the MySQL cache
#=====================================================================================

sub MySQLCacheAddBuffer ($$) {

  my ( $TableName, $AddValues ) = @_;

  my $FieldName;
  my $FieldValue;
  my $FieldValues;

  my $CacheValues;

  if ( ! defined($CacheFieldNameStrings{$TableName}) ) {
    print STDERR MySQLMakeID() . ": Table '$TableName' has not been initialized with the 'AddTable' command\n"; 
    return 1;
  }

  if ( $CacheSizes{$TableName} >= $MaxCacheSize ) { 
    # if ( $TableName eq 'tbl_xyz' ) {
      # print "Flushing $TableName cache before adding buffer: CacheSize = '$CacheSizes{$TableName}'\n" }
    MySQLCacheFlush ($TableName);
  }

  $FieldValues = '';

  for $FieldName ( @{$CacheFieldNameArrays{$TableName}} ) {

    $FieldValue = $AddValues->{$FieldName};

    if ( ! defined($FieldValue) ) { $FieldValue  =  '' }                 # Make sure value is defined
    else                          { $FieldValue  =~ s/(["',\\])/\\$1/g } # Make sure that MySQL special chars are escaped

    if ( $FieldValues ) { $FieldValues =  $FieldValues . "," }

    $FieldValues =  $FieldValues . "'" . $FieldValue . "'";

  }

  $CacheValues = $CacheFieldValues{$TableName};

  if ( $CacheValues ) { $CacheValues = $CacheValues . ',' }

  $CacheValues = $CacheValues . '(' . $FieldValues . ')';

  $CacheFieldValues{$TableName} = $CacheValues;

  $CacheSizes{$TableName}++;

  # if ( $TableName eq 'tbl_xyz' ) {
    # print "Added buffer to $TableName cache: CacheSizes '$CacheSizes{$TableName}', CacheValues '$CacheValues'\n" }

  return 0;

}

#=====================================================================================
# Flush entries from MySQL cache
#=====================================================================================

sub MySQLCacheFlush ($) {

  my ( $TableName ) = @_;

  my $FlushTable;
  my @FlushTables,

  my $FieldNames;
  my $FieldValues;
  my $DupKeyCmd;

  my $MySQLCmd;

  if ( lc($TableName) eq 'all' ) { 
    for $FlushTable ( keys(%CacheFieldNameStrings) ) { push @FlushTables, $FlushTable }

  } elsif ( ! defined($CacheFieldNameStrings{$TableName}) ) {
    print STDERR MySQLMakeID() . ": Table '$TableName' has not been initialized with the 'AddTable' command\n"; 
    return 1;

  } else {
    push @FlushTables, $TableName;

  }

  FlushTable: for $FlushTable ( @FlushTables ) {

    $FieldValues = $CacheFieldValues{$FlushTable};

    $CacheFieldValues{$FlushTable} = '';
    $CacheSizes{$FlushTable}       = 0;

    if ( ! $FieldValues ) { next FlushTable }

    $FieldNames = $CacheFieldNameStrings{$FlushTable};
    $DupKeyCmd  = $CacheDupKeyCmds{$FlushTable};

#Removed DELAYED after moving to innodb
#$MySQLCmd = "INSERT DELAYED INTO $FlushTable ($FieldNames) VALUES $FieldValues";

 $MySQLCmd = "INSERT INTO $FlushTable ($FieldNames) VALUES $FieldValues";

    if ( $DupKeyCmd ) { $MySQLCmd = $MySQLCmd . ' ON DUPLICATE KEY UPDATE ' . $DupKeyCmd }

    return MySQLDoCmd($MySQLCmd);

  }

}

sub BuildLists ($$;$) {

  my ($Type, $Ref1, $Ref2) = @_;

  my $Ref1Type = ref($Ref1);
  my $Ref2Type = ref($Ref2);

  my $Name;
  my $NameList;
  my $Value;
  my $ValueList;

  my %Fields;

  my $RtnVal;

  $Type = lc($Type);

  my $TypeIndex = index('values set where orderby', $Type);

  # print "Type '$Type', TypeIndex '$TypeIndex', Ref1Type '$Ref1Type', Ref1 '$Ref1'\n";

  if ( $TypeIndex < 0 ) {

    print STDERR MySQLMakeID() . ": $Type is not a a valid type. Use 'values', 'set' or 'where'\n";
    return $RtnVal;

  } elsif ( $Ref1Type eq '' ) {

    if ( $Type eq 'values' ) {
      $RtnVal = '(' . $Ref1 . ') VALUES (' . $Ref2 . ')';
    } elsif ( $Type eq 'set' ) {
      $RtnVal = ' SET ' . $Ref1;
    } elsif ( $Type eq 'where' ) {
      $RtnVal = ' WHERE ' . $Ref1;
    } elsif ( $Type eq 'orderby' ) {
      $RtnVal = ' ORDER BY ' . $Ref1;
    }

  } elsif ( $Ref1Type eq 'SCALAR' ) {

    if ( $Type eq 'values' ) {
      $RtnVal = '(' . $$Ref1 . ') VALUES (' . $$Ref2 . ')';
    } elsif ( $Type eq 'set' ) {
      $RtnVal = ' SET ' . $$Ref1;
    } elsif ( $Type eq 'where' ) {
      $RtnVal = ' WHERE ' . $$Ref1;    
    } elsif ( $Type eq 'orderby' ) {
      $RtnVal = ' ORDER BY ' . $$Ref1;
    }

  } elsif ( $Ref1Type eq 'HASH' ) {

    for $Name ( keys(%$Ref1) )  {

      $Value = $Ref1->{$Name};

      if ( ! defined($Value) ) { $Value  =  '' }                 # Make sure value is defined
      else                     { $Value  =~ s/(["',\\])/\\$1/g } # Make sure that MySQL special chars are escaped

      $Fields{$Name} = $Value;

    }

    if ( $Type eq 'values' ) {

      while (($Name, $Value) = each %Fields ) {
        if ( $NameList ) {
          $NameList  = $NameList  . ','  . $Name;
          $ValueList = $ValueList . ',"' . $Value . '"';
        } else {
          $NameList  = $Name;
          $ValueList = '"' . $Value . '"';    
        }
      }

      $RtnVal = " ($NameList) VALUES ($ValueList)";

    } elsif ( $Type eq 'set' ) {
      $RtnVal = '';
      while (($Name, $Value) = each %Fields ) {
        if ( $RtnVal ) { $RtnVal = $RtnVal . ',' }
        $RtnVal = $RtnVal . $Name . '="' . $Value . '"';
      }
      $RtnVal = ' SET ' . $RtnVal;

    } elsif ( $Type eq 'where' ) {
      $RtnVal = '';
      while (($Name, $Value) = each %Fields ) {
        if ( $RtnVal ) { $RtnVal = $RtnVal . ' AND ' }
        $RtnVal = $RtnVal . '(' . $Name . '="' . $Value . '")';
      }
      $RtnVal = ' WHERE ' . $RtnVal;

    }

  } else {

    print STDERR MySQLMakeID() . ": Parameter two is unsupported reference type '$Ref1Type'\n";
    return $RtnVal;

  }

  return $RtnVal;

}

sub BuildListsInt ($$;$) {

  my ($Type, $Ref1, $Ref2) = @_;
  my $Ref1Type = ref($Ref1);
  my $Ref2Type = ref($Ref2);

  my $Name;
  my $NameList;
  my $Value;
  my $ValueList;

  my %Fields;

  my $RtnVal;

  $Type = lc($Type);

  my $TypeIndex = index('values set where orderby', $Type);

  # print "Type '$Type', TypeIndex '$TypeIndex', Ref1Type '$Ref1Type', Ref1 '$Ref1'\n";

  if ( $TypeIndex < 0 ) {

    print STDERR MySQLMakeID() . ": $Type is not a a valid type. Use 'values', 'set' or 'where'\n";
    return $RtnVal;

  } elsif ( $Ref1Type eq '' ) {

    if ( $Type eq 'values' ) {
      $RtnVal = '(' . $Ref1 . ') VALUES (' . $Ref2 . ')';
    } elsif ( $Type eq 'set' ) {
      $RtnVal = ' SET ' . $Ref1;
    } elsif ( $Type eq 'where' ) {
      $RtnVal = ' WHERE ' . $Ref1;
    } elsif ( $Type eq 'orderby' ) {
      $RtnVal = ' ORDER BY ' . $Ref1;
    }

  } elsif ( $Ref1Type eq 'SCALAR' ) {

    if ( $Type eq 'values' ) {
      $RtnVal = '(' . $$Ref1 . ') VALUES (' . $$Ref2 . ')';
    } elsif ( $Type eq 'set' ) {
      $RtnVal = ' SET ' . $$Ref1;
    } elsif ( $Type eq 'where' ) {
      $RtnVal = ' WHERE ' . $$Ref1;
    } elsif ( $Type eq 'orderby' ) {
      $RtnVal = ' ORDER BY ' . $$Ref1;
    }

  } elsif ( $Ref1Type eq 'HASH' ) {

    for $Name ( keys(%$Ref1) )  {

      $Value = $Ref1->{$Name};

      if ( ! defined($Value) ) { $Value  =  '' }                 # Make sure value is defined
      else                     { $Value  =~ s/(["',\\])/\\$1/g } # Make sure that MySQL special chars are escaped

      $Fields{$Name} = $Value;

    }

    if ( $Type eq 'values' ) {

      while (($Name, $Value) = each %Fields ) {
        if ( $NameList ) {
          $NameList  = $NameList  . ','  . $Name;
          $ValueList = $ValueList . ',"' . $Value . '"';
        } else {
          $NameList  = $Name;
          $ValueList = '"' . $Value . '"';
        }
      }

      $RtnVal = " ($NameList) VALUES ($ValueList)";

    } elsif ( $Type eq 'set' ) {
      $RtnVal = '';
      while (($Name, $Value) = each %Fields ) {
        if ( $RtnVal ) { $RtnVal = $RtnVal . ',' }
        $RtnVal = $RtnVal . $Name . '="' . $Value . '"';
      }
      $RtnVal = ' SET ' . $RtnVal;

    } elsif ( $Type eq 'where' ) {
      $RtnVal = '';
      while (($Name, $Value) = each %Fields ) {
        if ( $RtnVal ) { $RtnVal = $RtnVal . ' AND ' }
        $RtnVal = $RtnVal . '(' . $Name . '=' . $Value . ')';
      }
      $RtnVal = ' WHERE ' . $RtnVal;

    }

  } else {

    print STDERR MySQLMakeID() . ": Parameter two is unsupported reference type '$Ref1Type'\n";
    return $RtnVal;

  }

  return $RtnVal;

}

你問兩個問題。

如何捕獲MySQL警告?

1)如果語句執行但有一個mysql警告我想將其捕獲到last_sql_warning.txt

最簡單的方法是簡單地將MySQL警告提升為錯誤,您已經知道可以記錄這些錯誤。 這將解決這個問題: $DBHandle->do(q|SET sql_mode='traditional'|);

更難的方法是通過SHOW WARNINGS枚舉SHOW WARNINGS ,您可以檢查mysql_warning_count屬性是否報告遇到警告。 但是,在撰寫本文時, DBD::mysql不方便地僅為語句(而不是數據庫)句柄公開該屬性。

更新: DBD::mysql自4.025(2013-11-05)在數據庫句柄上支持此屬性,因此下面的代碼可以簡化為$dbh->{mysql_warning_count}檢查。

因此,您可能會這樣做:

my $warnings;
my $ok = eval {
           my $sth = $DBHandle->prepare($MySQLCmd);
           $sth->execute();
           $warnings = $sth->{mysql_warning_count};
           1;
         };

unless ($ok) {                   # Some error encountered
  ... # log it
} elsif ($warnings) {            # Some warning(s) encountered
  ... # open log file

  my $warnings = $DBHandle->selectall_arrayref('SHOW WARNINGS');
  for my $row (@$warnings) {
    # @$row is something like ('Warning', 1265, "Data truncated for column 'col' at row 1")
    ... # log it
  }
}


如何重試因特定錯誤而失敗的語句?

2)如果語句錯誤導致鎖定超時,我想重新提交查詢兩次

在錯誤處理分支中,檢查$DBHandle->err以查找您關心的MySQL錯誤代碼(可能沒有.1205ER_LOCK_WAIT_TIMEOUT ),並根據需要重試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM