d_i_r_t_y has asked for the wisdom of the Perl Monks concerning the following question:

ok, i don't think i've done anything stupid, yet stupid things keep happening. here's the deal.

for the convenience of my fellow perl haxors at my company, i have created a module which centralises a whole lot of basic code to handle http sessioning, cgi parameter-handling, db connections and the like. no probs.

what's got me stuped is the following routine -- given an sql statement, it prepares it, executes it and returns a statement handle (if a select statement was given), or number of insert rows/update rows/delete rows otherwise.

the problem is that the routine never returns an actual $sth statement handle, even when a given sql query is successful. within the routine, printing $sth prints the expected DBI::st object, but in client code, the returned $sth is always '', the null string.

here is the routine:

sub do_sql { my $this = shift; my $sql = shift || return; my $dbh = $this->get_db_connection(); eval { if ( $sql =~ /^select/i ) { $this->log_internal_notice("executing sql query: $sql"); my $sth = $dbh->prepare( $sql ); my $nmb = $sth->execute(); $this->log_internal_notice( $nmb == 1 ? "1 result" : "$nmb results" ); return $sth; } else { $this->log_notice("executing non-select sql: $sql"); return $dbh->do( $sql ); } }; if ( $@ ) { $this->log_warning("Caught exception executing sql: $@"); return; } }

and here is some client code:

my $sth = $my_module_object->do_sql( $sql ) || return "<p><i>There are currently no experiment steps in this +experiment</i></p>";

Any ideas?

All replies much appreciated...
dirty

Replies are listed 'Best First'.
Re: calling all DBI wizards...
by dvergin (Monsignor) on Mar 27, 2001 at 11:10 UTC
    Don't try to return from inside an eval.
    sub test1 { eval {return 1}; return 0; } sub test2 { my $tmp; eval {$tmp = 1}; return $tmp; } print test1(), test2();
    Prints:  01
Re: calling all DBI wizards...
by chromatic (Archbishop) on Mar 27, 2001 at 13:30 UTC
    Your eval blocks are too coarsely-grained. dvergin has pointed at the reason why:

    print eval { return 'Surprise!' };

    You could wrap the prepare() and execute() statements in an eval block, which is much improved, and is still in the spirit of your code. You'll want to move the $@ checking, though.