Re: Perl DBI and postgres - Mailing list pgsql-general

From SCassidy@overlandstorage.com
Subject Re: Perl DBI and postgres
Date
Msg-id OF48B8EB69.B63ECCA5-ON8825704C.005866EA-8825704C.005D6CDE@myoverland.net
Whole thread Raw
In response to Perl DBI and postgres  (david.best@sympatico.ca)
List pgsql-general
Hi,

Well, since we don't seem to have the actual code (you seem to have
"paraphrased" it), I can't tell for sure.

However,  here (assuming this is sort of the way you actually are using
it):
  my $target_sth = $target_dbh->prepare(
               q{ SELECT columns
                  FROM the table }) or "Can't prepare statement:
    $DBI::errstr";

You don't use "die" or "warn" or anything, so you don't know if the prepare
actually worked or not;  you just have a literal, instead.

It is complaining about the fetchrow_array, so it might be there that the
problem is occurring, since you can't fetch something that never executed
correctly.

In this statement:
    $repo_sth = $repo_dbh->prepare("INSERT into thetable
                                      (columns)
                                   VALUES (?, '$data')");

that does not appear to be the real INSERT statement, so who knows if it is
right.  Also, you should probably have a "my" on the $repo_sth (declared at
the top of the subroutine somewhere, since you use it outside the while).

In this statement:
  while (my ($data) = $target_sth->fetchrow_array()) {

fetchrow_array returns an array, not a single value.  I tried doing it this
way on a multi-column SELECT, and you just get the last column in $data
doing it this way - probably not what you want.

I am a little confused why you do a prepare and execute inside a loop using
placeholders, instead of just embedding the data (like you do with $data,
but not $snap_id).  You usually either use placeholders, or build the whole
statement, not both.   If you did the prepare outside the loop, and used
placeholders for both VALUES, you would not need to quote it first.  Also,
if you do embed it in the statement, unless you are absolutely sure that
the 2nd value inserted will never have any quotes or anything in it, you
would probably be wise to call $dbh->quote to properly quote it before you
do the INSERT.

E.g.:
  my $data_q=$repo_dbh->quote($data);
 $repo_sth = $repo_dbh->prepare("INSERT into thetable
                                      (column1, column2)
                                   VALUES (?, $data_q)");

If you don't have RAISE_ERROR turned on, you wouldn't have to do the eval,
you could just check the status after the prepare and execute statements.
E.g., something like:
  if (!($sth=$dbh->prepare($statement))) {
    warn("bad prepare for stmt $statement, error: $DBI::errstr");
    $err++;
  }
  if (!($rc=$sth->execute())) {
    warn("can't execute statement:\n$statement\nDB error: $DBI::errstr");
    $err++;
  }

Also, "finish" is normally used only when you need to make sure no data is
left over after a SELECT (if you only fetched part of a result set), so you
don't really need it on the $repo_sth handle used for the INSERT.  Probably
not on the other sth, either.  From the perldoc on DBI:

           Adding calls to "finish" after each fetch loop is a common
mistake, don't
           do it, it can mask genuine problems like uncaught fetch errors.

I assume that any real "rollback" is done in the calling routine if the
returned value $err is true.  Although, shouldn't you be checking $@  for
errors after each eval?  The way you have it, it will continue through the
while loop, I believe.  I don't know if that is what you want to do.

I could be missing something, too - just took a quick look.

Hope this helps,

Susan





                   

                   
                      david.best@sympatico.ca        To:       pgsql-general@postgresql.org
                   
                           Sent by:                  cc:
                   
                                                     Subject:  [GENERAL] Perl DBI and postgres
                   

                   
                      pgsql-general-owner@pos         |-------------------|
                   
                      tgresql.org                     | [ ] Expand Groups |
                   
                                                      |-------------------|
                   

                   
                           07/28/2005 07:05
                   
                      AM
                   

                   

                   




This is probably just a general DBI question but I get the following
errors when I run my code:

DBD::Pg::st fetchrow_array failed: no statement executing at ./snap.pl
line 110.
DBD::Pg::st fetchrow_array failed: no statement executing at ./snap.pl
line 110.

Line 110 is a disconnect statement:

$target_dbh->disconnect();

I have multiple functions which access a target database, take the
information and put it back into a repository.   They all follow this
format, the database handlers are passed in, statement handlers are
created and closed at the end of the function.

sub free_space {

 my $err=0;
 my ($repo_dbh, $target_dbh, $snap_id) = @_;
 my $target_sth = $target_dbh->prepare(
               q{ SELECT columns
                  FROM the table }) or "Can't prepare statement:
$DBI::errstr";
 $target_sth->execute() or die $DBI::errstr;

  while (my ($data) = $target_sth->fetchrow_array()) {
   eval {
    $repo_sth = $repo_dbh->prepare("INSERT into thetable
                                      (columns)
                                   VALUES (?, '$data')");
    $repo_sth->execute($snap_id) or die $DBI::errstr;
   };
  }
   # check for errors.. If there are any rollback
   if ( $@ ) {
      $err = 1;
   }

 $repo_sth->finish();
 $target_sth->finish();

 return $err;
}

The main function just opens connections to the repository and target
database and closes them at the end with disconnects and that is where the
error is occuring.

Any ideas?


---------------------------(end of broadcast)---------------------------
TIP 2: Don't 'kill -9' the postmaster







----------------------------------------------------------------------------------------------
See our award-winning line of tape and disk-based
backup & recovery solutions at http://www.overlandstorage.com
----------------------------------------------------------------------------------------------


pgsql-general by date:

Previous
From: Roman Neuhauser
Date:
Subject: Re: Cursor Issue??
Next
From: Richard Huxton
Date:
Subject: Re: How to optimize select count(*)..group by?