Here is a patch to the pod documentation of DBD::Oracle-1.16.

The patch alters the section headed 'Binding Cursors'.

The patch:

  * corrects an error. When passing a cursor back from Perl
    to PL/SQL, bind_param_inout _must not_ be used.

  * attempts to clear up a misunderstanding. It is not normally
    necessary to close cursors explicitly.

It also:

  * introduces the Oracle 9 pre-defined type SYS_REFCURSOR.

  * makes the examples compatible with 'use strict'.

I have tested my assertion that Oracle closes cursors
automatically. I have not added a test to the test suite
because a proper test requires access to views, including
V$OPEN_CURSOR, which ordinary users cannot see.

--
Charles Jardine - Computing Service, University of Cambridge
[EMAIL PROTECTED]    Tel: +44 1223 334506, Fax: +44 1223 334679

diff -ur DBD-Oracle-1.16.cursor-docs/Oracle.pm DBD-Oracle-1.16/Oracle.pm
--- DBD-Oracle-1.16.cursor-docs/Oracle.pm       2005-04-26 17:19:35.384862000 
+0100
+++ DBD-Oracle-1.16/Oracle.pm   2004-10-21 20:07:53.000000000 +0100
@@ -2393,13 +2393,12 @@
 =head1 Binding Cursors

 Cursors can be returned from PL/SQL blocks. Either from stored
-functions (or procedures with OUT parameters) or
-from direct C<OPEN> statements, as shown below:
+procedure OUT parameters or from direct C<OPEN> statements, as show below:

   use DBI;
   use DBD::Oracle qw(:ora_types);
-  my $dbh = DBI->connect(...);
-  my $sth1 = $dbh->prepare(q{
+  $dbh = DBI->connect(...);
+  $sth1 = $dbh->prepare(q{
       BEGIN OPEN :cursor FOR
           SELECT table_name, tablespace_name
           FROM user_tables WHERE tablespace_name = :space;
@@ -2410,7 +2409,7 @@
   $sth1->bind_param_inout(":cursor", \$sth2, 0, { ora_type => ORA_RSET } );
   $sth1->execute;
   # $sth2 is now a valid DBI statement handle for the cursor
-  while ( my @row = $sth2->fetchrow_array ) { ... }
+  while ( @row = $sth2->fetchrow_array ) { ... }

 The only special requirement is the use of C<bind_param_inout()> with an
 attribute hash parameter that specifies C<ora_type> as C<ORA_RSET>.
@@ -2418,46 +2417,33 @@
 "ORA-06550: line X, column Y: PLS-00306: wrong number or types of
 arguments in call to ...".

-Here's an alternative form using a function that returns a cursor.
-This example uses the pre-defined weak (or generic) REF CURSOR type
-SYS_REFCURSOR. This is an Oracle 9 feature. For Oracle 8, you must
-create your own REF CURSOR type in a package (see the C<curref.pl>
-script mentioned at the end of this section).
+Here's an alternative form using a function that returns a cursor:

   # Create the function that returns a cursor
-  $dbh->do(q{
-    CREATE OR REPLACE FUNCTION sp_ListEmp RETURN SYS_REFCURSOR
-    AS l_cursor SYS_REFCURSOR;
+  $sth1 = $dbh->prepare(q{
+    CREATE OR REPLACE FUNCTION sp_ListEmp RETURN types.cursorType
+    AS l_cursor types.cursorType;
     BEGIN
       OPEN l_cursor FOR select ename, empno from emp order by ename;
       RETURN l_cursor;
     END;
   });
+  # CREATE is executed in prepare().

   # Use the function that returns a cursor
-  my $sth1 = $dbh->prepare(q{BEGIN :cursor := sp_ListEmp; END;});
+  $sth1 = $dbh->prepare(q{BEGIN :cursor := sp_ListEmp; END;});
   my $sth2;
   $sth1->bind_param_inout(":cursor", \$sth2, 0, { ora_type => ORA_RSET } );
   $sth1->execute;
   # $sth2 is now a valid DBI statement handle for the cursor
-  while ( my @row = $sth2->fetchrow_array ) { ... }
+  while ( @row = $sth2->fetchrow_array ) { ... }

-A cursor obtained from PL/SQL as above may be passed back to PL/SQL
-by binding for input, as shown in this example, which explicitly
-closes a cursor:
+To close the cursor you (currently) need to do this:

-  my $sth3 = $dbh->prepare("BEGIN CLOSE :cursor; END;");
-  $sth3->bind_param(":cursor", $sth2, { ora_type => ORA_RSET } );
+  $sth3 = $dbh->prepare("BEGIN CLOSE :cursor; END;");
+  $sth3->bind_param_inout(":cursor", \$sth2, 0, { ora_type => ORA_RSET } );
   $sth3->execute;

-It is not normally necessary to close a cursor
-explicitly in this way. Oracle will close the cursor automatically
-at the first client-server interaction after the cursor statement handle is
-destroyed. An explicit close may be desirable if the reference to
-the cursor handle from the PL/SQL statement handle delays the destruction
-of the cursor handle for too long. This reference remains until the
-PL/SQL handle is re-bound, re-executed or destroyed.
-
 See the C<curref.pl> script in the Oracle.ex directory in the DBD::Oracle
 source distribution for a complete working example.



Reply via email to