I am trying to verify that I correctly understand something I saw in the DB2
Information Center.
I am running DB2 Personal Edition V8.2.1 on Windows. I came across the
following in the Info Center:
To return a result set from a procedure to the originating application, use
the WITH RETURN TO CLIENT clause. When WITH RETURN TO CLIENT is specified on
a result set, no nested procedures can access the result set.
This excerpt can be found on the page entitled "Returning result sets from
SQL and embedded SQL procedures".
Based on some experiments I have done with Java client programs calling SQL
PL stored procedures, I *think* the excerpt means that a result set returned
by a procedure will only be visible to the client application if the cursor
was declared WITH RETURN TO CLIENT and if the procedure is directly called
by the client application. In other words, if the cursor was declared WITH
RETURN TO CLIENT and the procedure itself was NOT directly called by the
client, the client is not going to be able to access the result set.
I've done some experiments that tend to support this understanding but I
want to be sure I'm not missing some other factor that explains this
behaviour.
I wrote the following procedures in the Development Center:
a) an SQL PL procedure called RTRN_SET which declares and opens a cursor
WITH RETURN TO CLIENT
b) an SQL PL procedure called RECEIVE01 which calls RTRN_SET and handles its
result set
c) an SQL PL procedure called RECEIVE02 which calls RTRN_SET but does
nothing at all with its result set
I tried the following tests in the Development Center:
a) I executed procedure RTRN_SET in the Dev. Ctr. as a standalone procedure
it worked fine and displayed the result set correctly.
b) I executed procedure RECEIVE1 in the Dev. Ctr., it called RTRN_SET and
failed on SQL0423N as soon as it attempted to allocate a cursor for the
result set.
c) I executed procedure RECEIVE2 in the Dev. Ctr., it called RTRN_SET and
ended cleanly. The result set was also visible in the "Results" panel of the
Output View.
I wrote some Java applications to call the same stored procedures:
i) ClientRtrnSet calls procedure RTRN_SET directly and displays its result
set.
ii) ClientReceive1 calls procedure RECEIVE1 which in turn calls procedure
RTRN_SET.
iii) ClientReceive2 calls procedure RECEIVE2 which in turn calls procedure
RTRN_SET.
When I executed the Java applications, I got the following results:
i) ClientRtrnSet works fine and displays the result set obtained by
procedure RTRN_SET.
ii) ClientReceive1 gets SQL0423N when it executes procedure RECEIVE1.
iii) ClientReceive2 executes RECEIVE2 successfully but then gets a
NullPointerException when it tries to access the result set obtained by
procedure RTRN_SET. The NullPointerException indicates that the result set
either doesn't exist or cannot be accessed by the Java client application.
My analysis of the various tests is:
- (a) and (i) both worked fine, exactly as they should have.
- (b) and (ii) failed, exactly as they should have. Procedure RECEIVE1 tried
to access a result set from called stored procedure RTRN_SET that had
defined the result set as WITH RETURN TO CLIENT. Since RECEIVE1 is another
procedure, not a client program, it was not allowed to look at the result
set.
- I'm not sure what to make of (c). I'm surprised that the result set was
visible in the Results page when executing RECEIVE2 in the Dev. Ctr. Since
RECEIVE2 didn't do anything with the result set from RTRN_SET, I expected
the result set to be unavailable to RECEIVE2 in the Dev. Ctr.
- I'm not sure what to make of (iii). I thought that the result set might be
accessible to ClientReceive2 since procedure RECEIVE2 only called RTRN_SET
but didn't touch its result set. The NullPointerException on the result set
suggests strongly that the result set is not accessible by the client.
That's why I think the excerpt I quoted at the top of the post means that a
client can only access a result set from a procedure whose cursor is defined
as WITH RETURN TO CLIENT *if the procedure is called **DIRECTLY** by the
client; in my case, RTRN_SET is NOT called directly by ClientReceive2, it is
called by procedure RECEIVE2 which in turn is called by ClientReceive2.
Therefore, the only legitimate way for a client application to get the
result set from RTRN_SET is to call it directly, never indirectly via an
intermediate procedure, assuming the result set is declared WITH RETURN TO
CLIENT.
Have I analyzed all of this correctly? If not, could someone tell me where
I've gone wrong?
Also, to take this all one step further, what exactly is the point behind
WITH RETURN TO CLIENT? Why not just use WITH RETURN TO CALLER in every case
and let the calling procedure always handle the result set(s) returned by
the called procedure?
By the way, I'd be happy to post the different programs and procedures I've
described in this post if it would help anyone understand the question or
answer it.
Rhino
---
rhino1 AT sympatico DOT ca
"There are two ways of constructing a software design. One way is to make it
so simple that there are obviously no deficiencies. And the other way is to
make it so complicated that there are no obvious deficiencies." - C.A.R.
Hoare