Example of GENERAL WITH NULLS linkage convention

Specify the GENERAL WITH NULLS linkage convention when you want to allow the calling program to supply a null value for any parameter that is passed to the stored procedure.

Examples

The following examples demonstrate how an assembler, C, COBOL, or PL/I stored procedure uses the GENERAL WITH NULLS linkage convention to receive parameters.

For these examples, assume that a C application has the following parameter declarations and CALL statement:

/************************************************************/
/* Parameters for the SQL statement CALL                    */
/************************************************************/
  long int v1;
  char v2[10];                /* Allow an extra byte for     */
                             /*  the null terminator        */
/************************************************************/
/* Indicator structure                                      */
/************************************************************/
  struct indicators {
    short int ind1;
    short int ind2;
  } indstruc;
  ⋮
  indstruc.ind1 = 0;         /* Remember to initialize the  */
                             /*  input parameter's indicator*/
                             /*  variable before executing  */
                             /*  the CALL statement         */
  EXEC SQL CALL B (:v1 :indstruc.ind1, :v2 :indstruc.ind2);
  ⋮

In the CREATE PROCEDURE statement, the parameters are defined as follows:

IN V1 INT, OUT V2 CHAR(9)

Assembler example

The following figure shows how a stored procedure that is written in assembler language receives these parameters.

*******************************************************************
*  CODE FOR AN ASSEMBLER LANGUAGE STORED PROCEDURE THAT USES      *
*  THE GENERAL WITH NULLS LINKAGE CONVENTION.                     *
*******************************************************************
B        CEEENTRY AUTO=PROGSIZE,MAIN=YES,PLIST=OS
         USING PROGAREA,R13
*******************************************************************
*  BRING UP THE LANGUAGE ENVIRONMENT.                             *
*******************************************************************
         ⋮
*******************************************************************
*  GET THE PASSED PARAMETER VALUES. THE GENERAL WITH NULLS LINKAGE*
*  CONVENTION IS AS FOLLOWS:                                      *
*  ON ENTRY, REGISTER 1 POINTS TO A LIST OF POINTERS. IF N        *
*  PARAMETERS ARE PASSED, THERE ARE N+1 POINTERS. THE FIRST       *
*  N POINTERS ARE THE ADDRESSES OF THE N PARAMETERS, JUST AS      *
*  WITH THE GENERAL LINKAGE CONVENTION. THE N+1ST POINTER IS      *
*  THE ADDRESS OF A LIST CONTAINING THE N INDICATOR VARIABLE      *
*  VALUES.                                                        *
*******************************************************************
         L     R7,0(R1)            GET POINTER TO V1
         MVC   LOCV1(4),0(R7)      MOVE VALUE INTO LOCAL COPY OF V1
         L     R7,8(R1)            GET POINTER TO INDICATOR ARRAY
         MVC   LOCIND(2*2),0(R7)   MOVE VALUES INTO LOCAL STORAGE
         LH    R7,LOCIND           GET INDICATOR VARIABLE FOR V1
         LTR   R7,R7               CHECK IF IT IS NEGATIVE
         BM    NULLIN              IF SO, V1 IS NULL
         ⋮
         L     R7,4(R1)            GET POINTER TO V2
         MVC   0(9,R7),LOCV2       MOVE A VALUE INTO OUTPUT VAR V2
         L     R7,8(R1)            GET POINTER TO INDICATOR ARRAY
         MVC   2(2,R7),=H(0)       MOVE ZERO TO V2'S INDICATOR VAR
         ⋮
         CEETERM  RC=0
*******************************************************************
*  VARIABLE DECLARATIONS AND EQUATES                              *
*******************************************************************
R1       EQU   1                   REGISTER 1
R7       EQU   7                   REGISTER 7
PPA      CEEPPA  ,                 CONSTANTS DESCRIBING THE CODE BLOCK
         LTORG ,                   PLACE LITERAL POOL HERE
PROGAREA DSECT
         ORG   *+CEEDSASZ          LEAVE SPACE FOR DSA FIXED PART
LOCV1    DS    F                   LOCAL COPY OF PARAMETER V1
LOCV2    DS    CL9                 LOCAL COPY OF PARAMETER V2
LOCIND   DS    2H                  LOCAL COPY OF INDICATOR ARRAY
         ⋮
PROGSIZE EQU   *-PROGAREA
         CEEDSA  ,                 MAPPING OF THE DYNAMIC SAVE AREA
         CEECAA  ,                 MAPPING OF THE COMMON ANCHOR AREA
         END   B

C example

The following figure shows how a stored procedure that is written in the C language receives these parameters.
#pragma options(RENT)
#pragma runopts(PLIST(OS))
#include <stdlib.h>
#include <stdio.h>
/*****************************************************************/
/* Code for a C language stored procedure that uses the          */
/* GENERAL WITH NULLS linkage convention.                        */
/*****************************************************************/
main(argc,argv)
  int argc;                       /* Number of parameters passed */
  char *argv[];                   /* Array of strings containing */
                                  /*  the parameter values       */
{
  long int locv1;                 /* Local copy of V1            */
  char locv2[10];                 /* Local copy of V2            */
                                  /*  (null-terminated)          */
  short int locind[2];            /* Local copy of indicator     */
                                  /*  variable array             */
  short int *tempint;             /* Used for receiving the      */
                                  /*  indicator variable array   */
  ⋮
  /***************************************************************/
  /* Get the passed parameters. The GENERAL WITH NULLS linkage   */
  /* convention is as follows:                                   */
  /* - argc contains the number of parameters passed             */
  /* - argv[0] is a pointer to the stored procedure name         */
  /* - argv[1] to argv[n] are pointers to the n parameters     */
  /*   in the SQL statement CALL.                                */
  /* - argv[n+1] is a pointer to the indicator variable array    */
  /***************************************************************/
  if(argc==4)                     /* Should get 4 parameters:    */
  {                               /*  procname, V1, V2,          */
                                  /*  indicator variable array   */
    locv1 = *(int *) argv[1];
                                  /* Get local copy of V1        */
    tempint = argv[3];            /* Get pointer to indicator    */
                                  /*  variable array             */
    locind[0] = *tempint;
                                  /* Get 1st indicator variable  */
    locind[1] = *(++tempint);
                                  /* Get 2nd indicator variable  */
    if(locind[0]<0)               /* If 1st indicator variable   */
    {                             /*  is negative, V1 is null    */
      ⋮
    }
    ⋮
    strcpy(argv[2],locv2);
                                  /* Assign a value to V2        */
    *(++tempint) = 0;             /* Assign 0 to V2's indicator  */
                                  /*  variable                   */
  }
}

COBOL example

The following figure shows how a stored procedure that is written in the COBOL language receives these parameters.

 CBL RENT
 IDENTIFICATION DIVISION.
************************************************************
* CODE FOR A COBOL LANGUAGE STORED PROCEDURE THAT USES THE *
* GENERAL WITH NULLS LINKAGE CONVENTION.                   *
************************************************************
 PROGRAM-ID.    B.
 ⋮
 DATA DIVISION.
 ⋮
 LINKAGE SECTION.
************************************************************
* DECLARE THE PARAMETERS AND THE INDICATOR ARRAY THAT      *
*  WERE PASSED BY THE SQL STATEMENT CALL HERE.             *
************************************************************
 01 V1  PIC S9(9) USAGE COMP.
 01 V2  PIC X(9).
*
 01 INDARRAY.
    10 INDVAR  PIC S9(4) USAGE COMP OCCURS 2 TIMES.
 ⋮
 PROCEDURE DIVISION USING V1, V2, INDARRAY.
************************************************************
* THE USING PHRASE INDICATES THAT VARIABLES  V1, V2, AND   *
*  INDARRAY WERE PASSED BY THE CALLING PROGRAM.            *
************************************************************
 ⋮
***************************
* TEST WHETHER V1 IS NULL *
***************************
  IF INDARRAY(1) < 0
    PERFORM NULL-PROCESSING.
 ⋮
****************************************
* ASSIGN A VALUE TO OUTPUT VARIABLE V2 *
*  AND ITS INDICATOR VARIABLE          *
****************************************
   MOVE '123456789' TO V2.
   MOVE ZERO TO INDARRAY(2).

PL/I example

The following figure shows how a stored procedure that is written in the PL/I language receives these parameters.

*PROCESS SYSTEM(MVS);
A: PROC(V1, V2, INDSTRUC) OPTIONS(MAIN NOEXECOPS REENTRANT);
 /***************************************************************/
 /* Code for a PL/I language stored procedure that uses the     */
 /* GENERAL WITH NULLS linkage convention.                      */
 /***************************************************************/
 /***************************************************************/
 /* Indicate on the PROCEDURE statement that two parameters     */
 /*  and an indicator variable structure were passed by the SQL */
 /*  statement CALL. Then declare them in the following section.*/
 /* For PL/I, you must declare an indicator variable structure, */
 /*  not an array.                                              */
 /***************************************************************/
   DCL V1 BIN FIXED(31),
       V2 CHAR(9);
   DCL
       01 INDSTRUC,
          02 IND1 BIN FIXED(15),
          02 IND2 BIN FIXED(15);
   ⋮
   IF IND1 < 0 THEN
    CALL NULLVAL;       /* If indicator variable is negative    */
                        /*  then V1 is null                     */
     ⋮
   V2 = '123456789';    /* Assign a value to output variable V2 */
   IND2 = 0;            /* Assign 0 to V2's indicator variable  */