Special Linkage for DB2 Stored Procedure

I try to learn COBOL  a little bit more deeply with VISUAL COBOL,  But I feel hard to understand someone's code like this:

******************************************************

       identification division.
       program-id. gip2trbl.

       environment division.
       configuration section.

       data division.
       working-storage section.
       01 TRBLINP-TYPE          PIC  X(01).  
       01 TRBLINP-SEARCH-DATA   PIC  X(40).

       
       LINKAGE SECTION.                                 
       01 TRBLINP.                                       
           05 TRBLINP-IO-LEN      PIC S9(04) COMP-5.   
           05 TRBLINP-IO-TEXT     PIC X(41).       
       01 OUTDATA PIC X(41).

       PROCEDURE DIVISION USING  TRBLINP, OUTDATA  .
      

        UNSTRING  TRBLINP-IO-TEXT (1:TRBLINP-IO-LEN)
       DELIMITED BY '><'                        
       INTO  TRBLINP-TYPE ,
       TRBLINP-SEARCH-DATA .       
                       
       
        move  TRBLINP-IO-TEXT  to  OUTDATA.    
   
           goback.
           
       end program gip2trbl.

**************************************************************

Then I created DB2 stored procedure on DB2 V10.5

I passed "1><611016007800011"  into stored procedure. 

I expected  TRBLINP-IO-LEN having the real length of the string which I passed  and TRBLINP-IO-TEXT has original string value.

I use out parameter to verify TRBLINP-IO-TEXT.  but I only get "<611016007800011",   not "1><611016007800011"


Could someone explain to me how to make it working correctly ?

Really appreciated.

  • If the value of TRBLINP-IO-LEN is set to 18 and the value of TRBLINP-IO-TEXT is set to "1><611016007800011" then after the unstring statement the following should be true:

    TRBLINP-TYPE  PIC  X(01) will = "1" because this is data before delimiter

    TRBLINP-SEARCH-DATA   PIC  X(40). will = 611016007800011 because this is data after delimiter

    TRBLINP-IO-TEXT     PIC X(41) will still have its original value of "1><611016007800011"

    It sounds like you might be moving the group item TRBLINP to the out parameter instead of the TRBLINP-IO-TEXT field or perhaps not setting the length field correctly before the call?

    Have you tried debugging this to check the value of the variables that are being passed in?

  • But that is true:

    using group item TRBLINP as input parameter.

    TRBLINP-IO-TEXT     PIC X(41)  still has TRBLINP's original value of "1><611016007800011"

    and

    TRBLINP-IO-LEN  has the length.

    I saw the above code working on Z/OS.

    Compiled with AMODE(31) RMODE(any).

    I am wondering ---

    How does that magic happen on Mainframe,  but not in Visual COBOL?

    Or some flags in Visual COBOL can also make that working?

    Really appreciated.

  • I am not really sure what "magic" it is to which you are referring? Can you show me what the call of this stored procedure looks like including the setup of the parameters and how you are returning the output param?

  • CREATE PROCEDURE "GIP2TRBL" (INOUT TRBLINP VARCHAR(41) CCSID EBCDIC FOR SBCS DATA)
        DYNAMIC RESULT SETS 1
        PARAMETER CCSID EBCDIC
        EXTERNAL NAME "GIP2RAM2"
        LANGUAGE COBOL
        MODIFIES SQL DATA
        PARAMETER STYLE GENERAL
        FENCED
        WLM ENVIRONMENT D2TIWLM3
        ASUTIME NO LIMIT
        COLLID GITCOLL1
        RUN OPTIONS 'MSGFILE(SYSOUT,FBA,121,0,ENQ),RPTSTG(OFF),RPTOPTS(OFF )'
        STAY RESIDENT NO
        COMMIT ON RETURN YES
        PROGRAM TYPE MAIN
        SECURITY DB2
        PARAMETER CCSID EBCDIC;

    Then I call that Procedure: GIP2TRBL with TRBLINP = '1><611016007800011'   on Z/OS

    I just do not understand :  how TRBLINP saves '1><611016007800011' into TRBLINP-IO-TEXT ?  (magic happened there)

    But in VIsual COBOL, TRBLINP saves only '<611016007800011' into TRBLINP-IO-TEXT.

    Complete identical COBOL code!

    Really appreciated for further explanation.

       

  • I think the problem is the parameter that you are passing to the stored procedure and you haven't shown me that yet.

    Can you show me what the actual call looks like to the stored procedure?

    You can define special host variables that handle variable length strings like varchars. They have to be defined like the first parameter in your stored procedure only they require that a level 49 be used for the elementary fields and not 05 as you have specified and then you can reference them by the group item name within your SP call:

    01 TRBLINP.                                      

         49 TRBLINP-IO-LEN      PIC S9(04) COMP-5.  

         49 TRBLINP-IO-TEXT     PIC X(41).      

    If you then set the text field to the data item and the length field to the actual length and use TRBLINP as the parameter name then it should work correctly.

    You cannot simply pass in a literal string to a SP that is expecting a variable length field but you must use a host variable as shown above.

  • Verified Answer

    Thank you Chris,

    I figured it out --

    //////////////////////////////////////////////////////////////////////

          LINKAGE SECTION.                                

          01 TRBLINP.                                      

              05 TRBLINP-IO-LEN      PIC S9(04) COMP-5.  

              05 TRBLINP-IO-TEXT     PIC X(41).      

          01 OUTDATA PIC X(41).

          PROCEDURE DIVISION USING  TRBLINP, OUTDATA  .

          UNSTRING  TRBLINP-IO-TEXT (1:TRBLINP-IO-LEN)

          DELIMITED BY '><'                        

          INTO  TRBLINP-TYPE ,

          TRBLINP-SEARCH-DATA .                          

           move  TRBLINP-IO-TEXT  to  OUTDATA.    

    /////////////////////////////////////////////////////////////////////////////////////

    CREATE PROCEDURE "GIP2TRBL" (INOUT TRBLINP VARCHAR(41),

    OUT OUTDATA  CHAR(41) )

    Tested ON  Z/OS mainframe , DB2 V10.1

    Tested with Visual COBOL,  ON WINDOWS 10 , DB2 V10.5 (EXPRESS-C)

    I got the same result:

    At beginning,  I make a mistake as:

    CREATE PROCEDURE "GIP2TRBL" (INOUT TRBLINP CHAR(41), OUT OUTDATA  CHAR(41) )

    Now,  correct it as:

    CREATE PROCEDURE "GIP2TRBL" (INOUT TRBLINP VARCHAR(41), OUT OUTDATA  CHAR(41) )

    Thank you again,

    -Jack

  • Verified Answer

    Thank you Chris,

    I figured it out --

    //////////////////////////////////////////////////////////////////////

          LINKAGE SECTION.                                

          01 TRBLINP.                                      

              05 TRBLINP-IO-LEN      PIC S9(04) COMP-5.  

              05 TRBLINP-IO-TEXT     PIC X(41).      

          01 OUTDATA PIC X(41).

          PROCEDURE DIVISION USING  TRBLINP, OUTDATA  .

          UNSTRING  TRBLINP-IO-TEXT (1:TRBLINP-IO-LEN)

          DELIMITED BY '><'                        

          INTO  TRBLINP-TYPE ,

          TRBLINP-SEARCH-DATA .                          

           move  TRBLINP-IO-TEXT  to  OUTDATA.    

    /////////////////////////////////////////////////////////////////////////////////////

    CREATE PROCEDURE "GIP2TRBL" (INOUT TRBLINP VARCHAR(41),

    OUT OUTDATA  CHAR(41) )

    Tested ON  Z/OS mainframe , DB2 V10.1

    Tested with Visual COBOL,  ON WINDOWS 10 , DB2 V10.5 (EXPRESS-C)

    I got the same result:

    At beginning,  I make a mistake as:

    CREATE PROCEDURE "GIP2TRBL" (INOUT TRBLINP CHAR(41), OUT OUTDATA  CHAR(41) )

    Now,  correct it as:

    CREATE PROCEDURE "GIP2TRBL" (INOUT TRBLINP VARCHAR(41), OUT OUTDATA  CHAR(41) )

    Thank you again,

    -Jack