PreviousEmbedded SQL Using DB2 COBSQLNext"

Chapter 25: SQL, DB2/2 and 32-bit COBOL

OS/2:
The 32-bit COBOL system for OS/2 provides more powerful and flexible techniques for integrating other products with COBOL programs than the 16-bit COBOL system does. This chapter describes how the support for DB2/2 SQL takes advantage of this expanded support.

25.1 Overview

DB2/2 SQL taking advantage of the extra flexibility in 32-bit COBOL systems enables you to optimize your code for 32-bit operation, and provides more flexible techniques for resolving calls when linking programs to .exe or .dll. The 32-bit support also provides support programs to allow you to code programs which are source-compatible between 16-bit and 32-bit systems (referred to in this chapter as generic).

The DB2/2 SQL support on the 16-bit COBOL systems requires specific coding techniques and directives to allow COBOL programs to use SQL. When animating or running .int or .gnt programs, the COBOL system provides programs to resolve the dynamic calls from the COBOL program to the DB2/2 APIs. This is required even for COBOL programs which only use EXEC SQL statements. EXEC SQL statements are converted to calls to the DB2/2 APIs automatically by the Compiler. When linking to .exe/.dll files in the 16-bit system, the API calls inserted by the Compiler or any manually coded API calls must be resolved when linking.

25.2 Compatibility Between 16-bit and 32-bit

When you code EXEC SQL statements in your program, the COBOL Compiler changes the EXEC SQL into calls to the SQL API routines. For 16-bit COBOL, the name of the API is prefixed with two underscore characters. For example, a call to the SQLGSTRT API is actually done by calling __SQLGSTRT. This is required in 16-bit COBOL in order to use the Installf SQL DLL provided with the COBOL system for SQL access from .int/.gnt programs. When linking, the 16-bit compiler removes the double underscores from the API name and makes the name an external reference. This external reference is resolved during the link step by providing the name of the appropriate DB2/2 link library file. Resolving the names during the link step is the equivalent of a litlink name.

For 32-bit OS/2 and AIX, the API names inserted by the Compiler are not prefixed with double underscores. This means that when running .int/.gnt programs your program calls the API directly, bypassing any middle layer. When linking, you can choose to have these names resolved at link-time or at execution. You control this by setting the LITLINK or NOLITLINK directive when compiling your program. If you use NOLITLINK (the default), the call is a dynamic call to the entry point in the appropriate DB2/2 .dll file. If you use LITLINK, the calls are created as external references which must be resolved at link-time.

If you are manually coding calls to the SQL API routines, the double underscore naming convention is supported by 32-bit COBOL on OS/2. These are provided if you need to maintain common source for these calls between 16-bit and 32-bit platforms. Calls to the double underscore names in 32-bit COBOL are actually a call to an entry point provided with the COBOL system which in turn calls the SQL API.

25.3 Manually Coded SQL API Calls

DB2/2 provides a number of APIs in addition to the EXEC SQL which can be called directly from your program. For example, SQLGINTP to retrieve the message text for a non-zero SQLCODE, or SQLGSTRD to start using a database. You can prefix the API name with or without the double underscore. If you call the name without the double underscores, you must use the calling convention of the DB2/2 API. If you code the call to the SQL API with the double underscores, you must use the calling convention of the entry point in the COBOL system which makes the API call.

If you do not need complete source compatibility with 16-bit systems, we would recommend calling the API's without the double underscores. This provides the best performance since it bypasses the middle layer in the COBOL system which makes the actual SQL API call.

25.3.1 Calling Convention

For the DB2/2 SQL APIs, there are two aspects of the calling convention. One is the order of the parameters and the other is whether the calling program (caller) cleans up the stack or the called program (callee) cleans up the stack. If you provide the parameters in the wrong sequence, the API will fail with a non-zero return code or SQLCODE.


Warning: If the calling convention regarding which program clears the stack is set wrong, stack corruption occurs resulting in serious failures, for example run time error 114 (OS/2 trap), or perform or call operations not returning control properly. These failures will probably not occur at the SQL API call but somewhere later in your program. Also, in .int code during animation, these symptoms are less likely to appear. Care must be taken when coding and final testing of the .gnt, .exe or .dll file is necessary to confirm this.


The calling convention used is indicated on the CALL statement and is documented completely in your Programmer's Guide to Writing Programs. For the SQL APIs, there are two calling conventions:

0 Normal parameter order, caller clears stack
1 Reverse parameter order, caller clears stack

To call the SQLG APIs without the double underscore, use calling convention 0 or 1. If you use calling convention 0, provide the parameters in the sequence documented in the IBM manual for the section Generic SQLG API syntax in the APIs section. Note this is opposite of what is done with 16-bit COBOL. Calling convention 0 in 16-bit requires the parameters be provided in reverse order. Calling the APIs without the double underscore name is a native call directly to the DB2/2 API DLL.

If you want consistency in your source code for calls to the APIs, prefix the API names with the double underscore as you would for 16-bit COBOL and list the parameters as described in the COBOL APIs section of the DB2/2 Programming Reference. This is just the opposite of what you would code for direct calls without the double underscore.

If it is more important to you to optimize your code for 32-bit or to simplify the link requirements for .exe/ .dll, you should code calls to the SQLG API's without the double underscore.

25.4 Using the IBM DB2/2 Manual for API Calls

The IBM DB2/2 Programming Reference manual documents accessing SQL APIs from COBOL and from non-COBOL applications. The DB2/2 SQL APIs support both 16-bit and 32-bit applications.

The COBOL section in the DB2/2 Programming Reference manual was written to demonstrate the use of SQL APIs for the 16-bit COBOL systems using calling convention 0 and show that you should use the double underscores when making an API call.

The section Generic Syntax of the IBM manual shows the API calls with the parameters in the reverse order from the COBOL section and does not use the double underscore names.

The 16-bit COBOL systems require the use of the COBOL syntax. The 32-bit OS/2 COBOL system can support the COBOL syntax or the Generic Syntax. The Generic Syntax will result in the best performance on the 32-bit COBOL system.

If you want to use the Generic Syntax in a 32-bit COBOL application but still maintain close compatibility with the 16-bit syntax, you should use a calling convention of 1 and list the parameters in the reverse order. This results in the same parameter sequence for Generic and COBOL sequences with only the name of the called program being different.

Example

In the section COBOL syntax in your IBM manual, the SQLGINTP call is documented as:

call "__SQLGINTP" using by reference buffer
                        by reference sqlca
                        by value     line-width
                        by value     buffer-size

In the section Generic Syntax in your IBM manual, the same API is documented as:

SQLGINTP(buffer-size, line-width, sqlca, buffer)

where buffer-size and line-width are two byte integers and buffer and sqlca are pointers.

The appropriate COBOL CALL statements are:

        call "__SQLGINTP" using by reference buffer
                                by reference sqlca
                                by value     line-width
                                by value     buffer-size
        call "SQLGINTP"   using by value     buffer-size
                                by value     line-width
                                by reference sqlca
                                by reference buffer
     call CC1 "SQLGINTP"   using by reference buffer
                                 by reference sqlca
                                 by value     line-width
                                 by value     buffer-size

For 16-bit COBOL, you could instead use calling convention 3 which is the Pascal calling convention and you can list the parameters as defined in the section Generic Syntax; but, this calling convention must not be used for 32-bit COBOL. For example:

     call CC3 "__SQLGINTP" using by value     buffer-size
                                 by value     line-width
                                 by reference sqlca
                                 by reference buffer

Calling conventions are defined in the Special-Names paragraph in the Configuration Section (0 is the default if none specified). For these examples, use:

 environment division.
 configuration section.
 special-names.
     call-convention 1 is cc1
     call-convention 3 is cc3.

25.4.1 Corrections to the IBM DB2/2 Manual for API Calls

The IBM manual contains an error in the description of the SQLGMIGD API in the COBOL examples - a parameter is missing. The SQLGMIGD is documented correctly in the APIs section. Also, the SQLGFROL API is documented inconsistently between the COBOL and APIs sections. That is, the length codes passed are described as being passed by reference in the COBOL section but the APIs section shows them passed by value consistent with length codes for all other APIs. If you call the SQLGFROL API without the double underscore, it appears that both techniques work. However, if you use the double underscore name (__SQLGFROL), you must adhere to the API description and pass the lengths by value.

25.5 The PRE Option of the SQL Directive

The PRE option of the SQL directive causes the 32-bit COBOL system to load support for the double underscore SQL API entry point names and dynamically load the DB2/2 API DLL at run time. The PRE option must be used when you code calls to the SQL API's in your program using the double underscore names, even if it is linked to form an .exe/.dll file. The PRE option is the default when compiling SQL programs.

The PRE option is also required to resolve any dynamic calls to the SQL APIs. All calls are dynamic unless you call the API name as a literal and use the LITLINK(1) directive. A calling convention is also available to cause a call to a literal name to be litlinked even when using nolitlink or LITLINK(2). This is calling convention 8 - see your COBOL system documentation for details. When using EXEC SQL or manually coded API calls from .int/.gnt programs, the calls are always dynamic regardless of the calling convention used in the call statement.

When linking, calls which use a COBOL variable as the program name are not affected by litlink and are always dynamic calls. Calls from .int/.gnt programs are always dynamic. When a call is litlinked, the API name becomes an external reference which must be resolved when linking and the appropriate link libraries and/or object files must be available to the linker. Dynamic calls (not litlinked) are resolved at execution time by the COBOL run-time system. The entry points for dynamic calls only need to be loaded once, they do not have be loaded by each called subroutine which uses SQL.

The calls to the API's inserted into your program to process EXEC SQL statements are also dynamic calls to the API unless you use the LITLINK(1) directive. That is, these calls are inserted into your program as calls to a literal value similar to manually coding them in your program. The calls inserted by the Checker on 32-bit COBOL do not use the double underscore names.

If you do not need to use the INIT option and you did not manually code any API calls using the double underscore names, you can eliminate the need for the PRE option by loading the SQL API DLL in your program. This would simplify the link requirements for EXE and DLL programs. This can be done by setting a procedure pointer to the DLL name you want loaded. For example:

    01  LOAD-DLL-PTR            USAGE PROCEDURE-POINTER.
    SET LOAD-DLL-PTR TO ENTRY "SQLAPI32.DLL".

You cannot load the DLL in this manner when using the INIT option because the API calls made by INIT are performed before any COBOL statements you code. The PRE option inserts code prior to the INIT code to load the API's.

25.6 The INIT Option of the SQL Directive

The INIT option of the SQL directive causes calls to be inserted into your program to assist in DB2/2 initialization and termination. See the chapter Embedded SQL Using DB2 for details of this processing. When linking your application, the SQLINIT .obj must be specified on the link command line. This SQLINIT module calls the SQL APIs to perform the processing indicated by the INIT option.

There are two SQLINIT .obj programs provided with the 32-bit COBOL system. One is named sqlinit.obj and contains dynamic calls to the SQL APIs. The other is named sqlinit.obl and contains litlinked calls to the SQL APIs. These both perform the same processing - the only difference is the type of call to the SQL API. The program sqlinit.obj can be used for all combinations of linking as long as the PRE option is also used.

You can avoid the need for the PRE option and its corresponding .obj programs if you use the LITLINK(1) directive and your program contains only the following:

For this case, specify the sqlinit.obl program on the command line for the link. You must provide the extension of .obl as the linker defaults to using .obj. You could also rename this program but be sure to perform the rename after any updates you apply to the COBOL system to ensure you are using the latest version of this object program.


Note: The PRE option of the SQL directive is the default. To eliminate the need for the SQLPRE object programs when linking for this case, you must specify NOPRE after the INIT option.


25.7 Running .int/.gnt Programs

For programs compiled with the INIT or PRE options on the SQL directive you must have utils.lbr and _sqle3x.gnt in your COBDIR path.

PRE and INIT Examples:

  1. Programs with only EXEC SQL statements:

  2. Programs with manually coded API calls with double underscores:

  3. Programs with manually coded API calls without double underscores:

25.8 Running .exe/.dll Programs

The following sections explain how to run .exe/.dll programs compiled using different forms of the LITLINK COmpiler directive.

25.8.1 NOLITLINK Directive

For programs compiled with the SQLPRE directive you must do one of the following:

For programs compiled with the INIT option of the SQL directive you must do one of the following:

For programs with manually coded calls to the SQL APIs with the double underscore prefix, you must do one of the following:

PRE and INIT examples:

The examples for NOLITLINK are the same as for .int/.gnt programs.

25.8.2 LITLINK or LITLINK(1) Directive

For programs which use EXEC SQL or call the SQL APIs without the double underscore prefix include the DB2/2 sql_dyn.lib in your link statement library list

For programs which call the SQL APIs with the double underscore prefix include _sqle3x.obj in your link statement object file list

For programs compiled with the SQLPRE directive include _sqlprld.obj and _sqle3x.obj in your link statement object file list

For programs compiled with the INIT option include sqlinit.obj or sqlinit.obl in your link statement object file list as described in the section for the INIT option.

PRE and INIT examples:

  1. Programs with only EXEC SQL statements:

  2. Programs with manually coded API calls with double underscores:

  3. Programs with manually coded API calls without double underscores:

25.8.3 LITLINK(2) Directive

The LITLINK(2) directive removes the double underscore from the API name, resulting in a native call to the API. Thus, you should not use the double underscore names for calls to the APIs if you intend to use the LITLINK(2) directive. If you do code the double underscore names, you must order the parameters as if the double underscore were not used. You will also need to include the DB2/2 sql_dyn.lib in your link statement library list.

With LITLINK(2), calls using a literal and no double underscore name are processed as if NOLITLINK were used. Since the calls inserted to process EXEC SQL statements are inserted without double underscores, the SQLPRE directive is required to load the DB2/2 DLL to resolve the dynamic calls at execution. In other words, for programs which only use EXEC SQL, LITLINK(2) is equivalent to NOLITLINK.


Copyright © 1999 MERANT International Limited. All rights reserved.
This document and the proprietary marks and names used herein are protected by international law.

PreviousEmbedded SQL Using DB2 COBSQLNext"