in reply to Can I get the actual error for DBI->execute() ?

You could put something like this:
sub insertItem { (my $insertCom) = @_; $dbInsert=$db->prepare($insertCom) or die "DBI prepare failed! : $ +sth->err : $sth->errstr"; my $rows_inserted = $dbInsert->execute(); if ( $dbInsert->err ) { die "DBI ERROR Insert Failed! : $sth->err : $sth->errstr"; } return $rows_inserted; }
Or this will accomplish basically the same thing:
$db=DBI->connect('DBI:mysql:invoices',[username],[password], { RaiseEr +ror => 1, AutoCommit => 1 });

Replies are listed 'Best First'.
Re^2: Can I get the actual error for DBI->execute() ?
by cavac (Prior) on Jun 21, 2024 at 08:32 UTC

    Just a quick note: It might be helpful to use croak() from the Carp module instead of die(). That way, OP would get a backtrace to where the error originated and what the function arguments were.

    With die:

    #!/usr/bin/env perl use v5.40; do_something(); sub do_something() { broken_function(10); broken_function(17); return true; } sub broken_function($val) { die("Bla") unless($val == 10); }

    $ perl dietest.pl Bla at dietest.pl line 14.

    With croak:

    #!/usr/bin/env perl use v5.40; use Carp qw(croak); do_something(); sub do_something() { broken_function(10); broken_function(17); return true; } sub broken_function($val) { croak("Bla") unless($val == 10); }

    $ perl dietest.pl Bla at dietest.pl line 16. main::broken_function(17) called at dietest.pl line 11 main::do_something() called at dietest.pl line 7

    So, in your example, that would be:

    ... use Carp qw(croak); ... sub insertItem { (my $insertCom) = @_; $dbInsert=$db->prepare($insertCom) or die "DBI prepare failed! : $ +sth->err : $sth->errstr"; my $rows_inserted = $dbInsert->execute(); if ( $dbInsert->err ) { croak("DBI ERROR Insert Failed! : $sth->err : $sth->errstr"); } return $rows_inserted; }

Re^2: Can I get the actual error for DBI->execute() ?
by etj (Priest) on Jun 21, 2024 at 13:11 UTC
    $dbInsert=$db->prepare($insertCom) or die "DBI prepare failed! : $sth- +>err : $sth->errstr";
    Be warned this will interpolate $sth, and not call err etc on it. Instead, do:
    $dbInsert=$db->prepare($insertCom) or die "DBI prepare failed! : ${\$sth->err} : ${\$sth->errstr}";

      Unfortunately, not even that will work seeing as how $sth hasn't even been declared.


      🦛

        So the code below gave me the most detail. I tried checking for $dbHandle->err after the prepare statement but it returned nothing.

        And I just wanted to just be clear: setting RaiseError => 1 does cause the script to exit immediately, yes?

        Thanks for everyone's help.
        sub insertItem { (my $insertCom) = @_; $dbHandle=$db->prepare($insertCom); my $result = $dbHandle->execute(); if ($dbHandle->err || $dbHandle->errstr) { $logger->debug("err | $DBI::err | $DBI::errstr"); } return $result; }
      Yes quite correct. $sth came from some other code via copy and paste and is an error on my part. $DBI::err and $DBI::errstr would be the appropriate vars to use here.

      Once again, I prefer RaiseError in most circumstances. In most cases, there is nothing that the program can do about a fatal DB error. It usually makes the most sense to just stop. The OP showed very little of his code and even less explanation. It should be noted that "prepare" can be an "expensive" operation and, therefore most code attempts to prepare a statement once and use that statement many times.

      Perhaps it could be that whatever is driving the generation of multiple identical tables with different names, this can be simplified to a single table table with one extra column to represent that factor. That way you could have a single prepared statement that works with what were before multiple tables and now is a single table? The table name cannot be a variable in a prepared statement.