Dynamic operations offer a way to execute SQL commands that cannot
be completely defined until run time.  You accept part or all of
an SQL command that can be dynamically preprocessed from the user, then
use one of the following techniques to preprocess and execute the
command:
If the dynamic command is not a query, you can use
the PREPARE command to preprocess it, then execute it later
during the same transaction using the EXECUTE command.  Alternatively,
you can use the EXECUTE IMMEDIATE command to preprocess and
execute the dynamic command in one step.
If the dynamic command is a query, you use special
data structures plus the following SQL commands to handle
the dynamic command:  PREPARE, DESCRIBE, DECLARE CURSOR, OPEN, FETCH,
and CLOSE.
To determine whether a dynamic command is a query, you
use the DESCRIBE command after preparing the dynamic command:
        The program accepts an SQL command from the user and stores
        it in a host variable named DynamicCommand.
   EXEC SQL PREPARE DynamCommand FROM :DynamicCommand;
        After the command is prepared, the DESCRIBE command is used
        to determine whether the prepared command is a SELECT command.
   EXEC SQL DESCRIBE DynamCommand INTO SQLDA;
        The SQLDA.SQLD field of the SQLDA is examined to determine
        whether the dynamic command is a query.
   if SQLDA.SQLD = 0 then       (*the command is not a query*)
     begin
     EXEC SQL EXECUTE DynamCommand;
     .
     .
     .
   else if SQLDA.SQLD > 0 then  (*the command is a query*)
     .
     .
     .
         A non-query can be executed with the EXECUTE
         command, but a query requires special handling.
 | 
Dynamic queries require special handling because you may not
know in advance what a query result will look like.  The number and
type of columns, the existence of null values, the column names...this
and other information may need to be obtained by the program at
run time because it is not known at programming time.
To obtain the information needed to parse any query result at
run time, you use three special data structures in your
program:  the SQLDA, a format array, and a data buffer:
The SQLDA (SQL Description Area) and the format array
contain information about the query result.  These data structures
have the format described in the chapter, "Host Variables."
The data buffer holds one or more rows fetched from the
query result.  Its format is also described in the chapter, "Host Variables."
The following example summarizes how you declare and use these data
structures:
   const
        OK            =    0;
        Notfound      =  100;
        NbrFmtRecords =  255; (*maximum number of columns*)
        MaxDataBuff   = 1600; (*maximum number of bytes the program*)
                              (*allows in each fetch; 1600 bytes *)
                              (*accommodates the display of 20*)
                              (*80-character lines*)
   var
        EXEC SQL BEGIN DECLARE SECTION;
        DynamicCommand        : String[1024] (*maximum length of*)
                                             (*a dynamic command*)
        EXEC SQL END DECLARE SECTION;
        EXEC SQL INCLUDE SQLDA;
                     (*declaration of SQLDA*)
        SQLFmts    : array[1..NbrFmtRecords] of SqlFormat_Type;
                     (*declaration of format array*)
        DataBuffer : packed array[1..MaxDataBuff] of char;
                     (*declaration of data buffer*)
   .
   .
   .
   procedure ExecuteDynamCmd;
   begin
     with SQLDA do  (*You must set two SQLDA fields before DESCRIBE*)
       begin
       Sqln      := NbrFmtRecords; (*number of records in format array*)
       SqlFmtArr := waddress(SQLFmts); (*address of format array*)
       end;
     .
     .        The program accepts a dynamic command.
     EXEC SQL PREPARE DYNAMCOMMAND FROM :DYNAMICCOMMAND;
     .
     .        Status checking is done.
     EXEC SQL DESCRIBE DYNAMCOMMAND INTO SQLDA;
 | 
     if SQLDA.SQLD = 0             (*dynamic command is not a query*)
     .
     .     The program executes the dynamic command.
     .
     else if SQLDA.SQLD > 0 then   (*dynamic command is a query*)
     begin
       EXEC SQL DECLARE DYNAMCURSOR CURSOR FOR DYNAMCOMMAND;
       EXEC SQL OPEN DYNAMCURSOR;
       .
       .   If SQLCODE is 0, rows in the query result can be
           fetched.  First, however, you must set three
           SQLDA fields.
       with SQLDA do
       begin
         SqlBufLen := sizeof(DataBuffer); (*bytes in data buffer*)
         SqlNRow   := SqlBufLen DIV SqlRowLen;
                      (*number of rows to fetch into data buffer*)
         SqlRowBuf := waddress(DataBuffer); (*address of data buffer*)
       end;
       while SQLCA.SQLCODE = OK do
       begin
         EXEC SQL FETCH DYNAMCURSOR USING DESCRIPTOR SQLDA;
         if SQLCA.SQLCODE <> OK then
         begin
           if SQLCA.SQLCODE = NotFound then
              writeln('No more rows qualify.')
           else
           SQLStatusCheck;
         end;
         else
         DisplaySelect;
       end;
   .
   .
   .
   procedure DisplaySelect;
           This procedure parses the data buffer and displays
           rows fetched.  For each column in each row of the
           query result, various fields in the format array
           are used to identify where data values are located
           in the data buffer as well as the data type of
           these values and null value information.
 | 
Techniques for parsing the data buffer and more examples of
dynamic preprocessing are in the chapter, "Using Dynamic Operations."