On Sat, 17 Mar 2001, Steven N. Hirsch wrote:

> I'm running out of ideas trying to get a call to a DB2 stored
> procedure to return a result set to the DBI::DB2 interface.

And, with too much time on my hands this weekend I think I've nailed the
problem.  The DB2 driver tries to get the column description for the
result set as early as possible. When no parameter markers are present it
calls dbd_describe() immediately after preparing the SQL statement.  If
parms are present, it makes the call just prior to
SQLExecute().

However, according to the CLI API documents this is only safe for 'SELECT'
statements but NOT for stored procedure calls.  In the latter case, the
column descriptions are available only after SQLExecute() has been called.

The following patch gets it working for CALL statements, but I haven't
done much testing to see what (if anything) might be adversely
affected.  In particular, I'm wondering if there is a way (besides parsing
the actual SQL) to determine in dbd_st_prepare() that a stored procedure
call is being invoked and switch logic accordingly.

Can't believe no one else has run into this (patch against DBD-DB2-0.74).

Steve


--- dbdimp.c.orig       Wed Sep  6 17:19:50 2000
+++ dbdimp.c    Sun Mar 18 22:20:51 2001
@@ -1137,8 +1137,6 @@
     if (params > 0 ){
         /* scan statement for '?', ':1' and/or ':foo' style placeholders*/
         dbd_preparse(imp_sth, statement);
-    } else {    /* assuming a parameterless select */
-        dbd_describe(sth,imp_sth );
     }
 
     /* initialize sth pointers */
@@ -1489,16 +1487,16 @@
       }
     }
 
+    ret = SQLExecute(imp_sth->phstmt);
+    ret = check_error( sth, ret, "SQLExecute failed" );
+    if (ret < 0)
+        return(-2);
+
     /* describe and allocate storage for results        */
     if (!imp_sth->done_desc && !dbd_describe(sth, imp_sth)) {
         /* dbd_describe has already called check_error()        */
         return -2;
     }
-
-    ret = SQLExecute(imp_sth->phstmt);
-    ret = check_error( sth, ret, "SQLExecute failed" );
-    if (ret < 0)
-        return(-2);
 
     if( imp_sth->bind_names && imp_sth->bHasOutput )
     {

Reply via email to