Skip to main content

Problem:

There are two things to note when coding dynamic SQL in COBOL

Resolution:

First, according to DB2's syntax diagram, preparing from a string literal only works in PL/I so that's the reason why the mfuser\\projects\\demo\\sqldemo\\Test5 program  EXEC SQL PREPARE won't compile

           EXEC SQL PREPARE EM-INSERT FROM

              'INSERT INTO EMPLOYEE                        

      -       '   VALUES (?,?,?,?,?,?,?,?,?,?)'                       

    ________________________________________________________________________

   |                                                                        |

   | >>__PREPARE__statement-name__________________________________________> |

   |                                                                        |

   | >__ ______________________________________________ __________________> |

   |    |_INTO__descriptor-name__ ___________________ _|                    |

   |                             |         _NAMES__  |                      |

   |                             |_USING__|_LABELS_|_|                      |

   |                                      |_ANY____|                        |

   |                                      |_BOTH___|                        |

   |                                                                        |

   | >__ _ ___________________________________ __FROM__host-variable_ ___>< |

   |    | |                                (1)|                      |      |

   |    | |_ATTRIBUTES__attr-host-variable____|                      |      |

   |    |                         (2)                                |      |

   |    |_FROM__string-expression____________________________________|      |

   |                                                                        |

   | Notes:                                                                 |

   | (1)  attr-host-variable must be a string host variable and the content |

   |      must conform to the rules for attribute-string. The ATTRIBUTES    |

   |      clause can only be specified before host-variable.                |

   |                                                                        |

   | (2)  string-expression is only supported for PLI.                      |

   |                                                                        |

   |________________________________________________________________________|

Second, it is correct to use a host variable of type VARCHAR in the revised program.  DB2 SQL reference says the following about the type of host variable that should be used in a PREPARE statement in COBOL.

host-variable

Must identify a host variable that is described in the application program in accordance with the rules for declaring string

| variables. If the source string is over 32KB in length, the

| host-variable must be a CLOB or DBCLOB variable. The maximum

| source string length is 2MB although the host variable can be

| declared larger than 2MB. An indicator variable must not be specified. In COBOL and Assembler language, the host variable must be a varying-length string variable. In C, the host variable must not be a NUL-terminated string.

There is another pitfall in the code snippet in that the length part of the VARCHAR host variable is not the exact length of the SQL string literal.

The STRING verb as a better way of putting together the SQL string into a VARCHAR host variable.  

           MOVE 1 TO WS-SQL-STMT-LEN

           STRING 'INSERT INTO TUTORIAL.EMPLOYEE VALUES ' ç String literal 1

                       DELIMITED BY SIZE                                                              

                  '(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'     ß String literal 2

                       DELIMITED BY SIZE

             INTO WS-SQL-STMT-TXT  ß Destination field

             WITH POINTER WS-SQL-STMT-LEN

             ON OVERFLOW GO TO 920-SQL-BUFFER-OVERFLOW

           END-STRING

           SUBTRACT 1 FROM WS-SQL-STMT-LEN

The key is the WITH POINTER clause.  This clause specifies the character position in the destination field, WS-SQL-STMT-TXT.  Moving a one there initially means to start writing in character position one of the destination.  The DELIMITED BY SIZE after each string literal simply means the string will be written to destination field in its entirety.  When all string literals have been processed, the value in the pointer field, WS-SQL-STMT-LEN, will contain a value that's one character position beyond the last character in the destination field, WS-SQL-STMT-TXT.  Therefore the exact length of the VARCHAR can be derived by subtracting one from the pointer value calculated by STRING statement.  Having the exact length of the string in the length part of the varchar host var ensures that it doesn't look beyond the SQL string and accidentally get the junk that might exist in the text part.

Attachments:

DYNINS.zip

Old KB# 2532

#MFDS
#EnterpriseDeveloper