Re: [svn:DBD-Pg] r9821 - in DBD-Pg/trunk: . t

"Ben Tilly" <[email protected]>
Newsgroups gmane.comp.db.postgresql.dbdpg
Message-ID <[email protected]>
On 8/7/07, Andrew Dunstan <[email protected]> wrote:
> Ben Tilly wrote:
> > -Although PostgreSQL has a cursor concept, it has not been used in the current
> > +Although PostgreSQL supports cursors, they have not been used in the current
> >  implementation. Cursors in PostgreSQL can only be used inside a transaction
> >  block. Because only one transaction block at a time is allowed, this would
> >  have implied the restriction not to use any nested C<SELECT> statements. Hence
[...]
> It is no longer true that cursors only work inside a single transaction.
> Postgres now has "WITH HOLD" cursors that persist to the end of a
> session if not closed. This has been true since 7.4, which is quite a
> long time, really. See docs on "DECLARE" for details.

Good point.  Here is a patch that takes that into account.

Cheers,
Ben

--- Pg.pm.bak   2007-08-07 09:34:33.000000000 -0700
+++ Pg.pm       2007-08-07 11:12:14.000000000 -0700
@@ -3401,13 +3401,32 @@

 =head2 Cursors

-Although PostgreSQL has a cursor concept, it has not been used in the current
-implementation. Cursors in PostgreSQL can only be used inside a transaction
-block. Because only one transaction block at a time is allowed, this would
-have implied the restriction not to use any nested C<SELECT> statements. Hence
-the C<execute> method fetches all data at once into data structures located in
-the front-end application. This approach must to be considered when selecting
-large amounts of data!
+Although PostgreSQL supports cursors, they have not been used in the current
+implementation. When DBD::Pg was defined, cursors in PostgreSQL could only be
+used inside a transaction block. Because only one transaction block at a time
+is allowed, this would have implied the restriction not to use any nested
+C<SELECT> statements. Therefore the C<execute> method fetches all data at
+once into data structures located in the front-end application. This fact
+must to be considered when selecting large amounts of data!
+
+You can use cursors in your application, but you'll need to do a little
+work.  First you must declare your cursor.  Now you can issue queries against
+the cursor, then select against your queries.  This typically results in a
+double loop, like this:
+
+  # Note: WITH HOLD is only available from PostgreSQL 7.4 on.  It is not
+  # needed if AutoCommit is off.
+  $dbh->do("DECLARE csr CURSOR WITH HOLD FOR $sql");
+  while (1) {
+    my $sth = $dbh->prepare("fetch 1000 from csr");
+    $sth->execute;
+    last if 0 == $sth->rows;
+
+    while (my $row = $sth->fetchrow_hashref) {
+      # Do something with the data.
+    }
+  }
+  $dbh->do("CLOSE csr");

 =head2 Datatype bool
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.