I had a similar problem. Looks like that when a script runs fetchrow_array and there is no more lines to be returned, DBD kill the cursor and , so, any try to access methods or attributes of the statement handle ($sth) will raise the error "fetch() without execute()".
I solved my problem with a conditional :
$sth->execute() or die "Error executing [$sqlcmd] : " . $dbh->errstr;
$end_fetch = 0;
do {
if (! $end_fetch) {
($key_col, $col1, $col2, $col3) = $sth->fetchrow_array;
if (! defined $key_col) {
$end_fetch = 1;
}
}
...
} while ($some_condition);