The OpenESQL preprocessor enables you to access a relational database via an ODBC driver by embedding SQL statements within your COBOL program.
Unlike separate preprocessors, OpenESQL is controlled by specifying the SQL directive when you compile your application.
OpenESQL provides an alternative for developers using ORACLE data sources, in the form of the ORACLE OCI interface. ORACLE OCI provides faster processing of SQL statements than the more generic ODBC interface that OpenESQL normally uses. To use this interface, you must compile your applications with the following directive:
sql(targetdb=ORACLEOCI)
When connecting to the Oracle server, use an Oracle Net8 service name in place of an ODBC data source name in the CONNECT statement. See your Oracle documentation on how to set up ORACLE Net8 services.
When you use Oracle OCI, be aware that the following OpenESQL functions are not supported:
When you compile a program that includes Embedded SQL statements, you must specify the Compiler directive SQL and appropriate options. The ODBC driver that your program calls depends on the particular data source that you are accessing.
You can specify the SQL directive anywhere where you can specify any other Compiler directive, that is:
$set sql(dbman=odbc, autocommit)
cob -V testconn.cbl -C"anim SQL(DBMAN=ODBC)"
Note: You cannot use a mixture of these methods - you must use one only.
The SQL Compiler directive options are given below:
Option | Description | ||||||
ALLOWNULLCHAR | Allows programs to use PIC X(n) host variables, and to select/insert/update hexadecimal characters in CHAR columns without changing source to use SQL TYPE BINARY host variables. | ||||||
[NO]ANSI92ENTRY | If this is set, OpenESQL conforms to the SQL ANSI 92 entry level standard. | ||||||
[NO]AUTOCOMMIT | If this is set, each SQL statement is treated as a separate transaction and is committed immediately upon execution. If this is not set, and the ODBC driver you are using supports transactions, statements must be explicitly committed (or rolled back) as part of a transaction. | ||||||
[NO]AUTOFETCH | Sets the AUTOFETCH attribute on SELECT statements that are run on Microsoft SQL Server data sources. Compiling with this directive can help the performance of your application. This directive works only if the program is also compiled with directive SQL(TARGETDB=MSSQLSERVER). | ||||||
[NO]CHECK | If this is set, each SQL statement is sent to the database at compilation time. If you specify statement checking at compilation time, you must also set DB and PASS. Note that this option is dependent on your driver and/or DBMS and in certain circumstances, invalid SQL statements will not be flagged. | ||||||
CHECKDUPCURSOR | If this is set, OpenESQL returns SQLCODE -19516 if the cursor is already open and the program is compiled with directive NOANSI92ENTRY. The default behavior when a program is compiled with NOANSI92ENTRY is to automatically close the cursor and then re-open it. | ||||||
CHECKSINGLETON | Causes OpenESQL to check if singleton SELECTs return more than one row when executed. If this occurs, OpenESQL sets SQLCODE to a -811. | ||||||
CONCAT=ascii character code | Specifies the ASCII character code to use for the CONCAT symbol (|). Use this directive only if you need to change the default, which is 33. | ||||||
CONNECTIONPOOL=[DRIVER | ENVIRONMENT | NONE] | Enables use of ODBC 3.0 connection pooling. When a connection is closed, the Driver Manager actually keeps it alive for a timeout period, and saves the overhead of re-establishing a connection from scratch if the application re-opens an identical connection. ODBC allows you to choose between having a pooling for an ODBC environment or for each driver. See your ODBC documentation for details. This option is only useful for applications that frequently open and close connections. Note that some environments, such as Microsoft Transaction Server (MTS), control connection pooling themselves. This option will probably improve the performance of ISAPI applications that are not running under MTS. Default is NONE. | ||||||
[NO]CTRACE | Causes debug information to be put into an sqltrace.txt file. Default is NOCTRACE. | ||||||
[NO]CURSORCASE | If ESQLVERSION is 2.0, CURSORCASE is implied. Default is NOCURSORCASE which means that cursor names are not case sensitive. CURSORCASE means that they are case sensitive. Note that in previous versions of OpenESQL, cursor names have been case sensitive. | ||||||
[NO]DB | The name of the data source to connect to. This option works in conjunction with the INIT and/or CHECK options. | ||||||
DBMAN=preprocessor | Specifies the preprocessor to use. This should always be set to
odbc, that is dbman=odbc. The .int file generated is the same except for the TARGETDB number embedded in the file. |
||||||
[NO]DECDEL | Eliminates the need for OpenESQL
to call the routine GetLocaleInfo for any variable that would store decimal
data. This routine is called every time the variable is accessed to return the
decimal delimiter used. In most cases, this is a period or comma. The options
for this directive are:
The default is NODECDEL, which causes OpenESQL to call GetLocaleInfo every time a decimal variable is referenced. |
||||||
[NO]DETECTDATE | If DETECTDATE is set, OpenESQL inspects character host variables
for ODBC escape sequences: {d<data>} - date {t<data>} - time {ts<data>} - timestamp and binds the parameter appropriately, rather than as a character column. This is necessary if your server does not have a suitable native character string date representation (for example, Microsoft Access). It is also useful for generic applications. It can, however, cause problems if you have other character columns that can legitimately contain data that starts with "{d", "{t" or "{ts". Default is NODETECTDATE. |
||||||
[NO]ESQLVERSION | Sets OpenESQL syntax level. | ||||||
[NO]FIPSFLAG | Enables FIPS flagging (NIST certification requirement only). Default is NOFIPSFLAG. | ||||||
[NO]IGNORE-NESTED=program-id | In nested programs, this is the program-id at which to start generating the database interface code. If the program file name matches the program-id, you can just specify IGNORE-NESTED. Default is NOIGNORE-NESTED. | ||||||
[NO]INIT | If this is set, the preprocessor automatically generates code to make the connection to the database. If you specify INIT, you must also specify DB and PASS. | ||||||
[NO]NIST | If this is set, OpenESQL will conform to the NIST interpretation of the SQL ANSI 92 entry level standard. | ||||||
NOT=ascii character code | Specifies the ASCII character code to use for NOT symbol (¬). Use this only if you need to change the default setting, which is 170. | ||||||
ODBCTRACE= [ALWAYS | NEVER | USER] | ODBCTRACE=USER enables you to control ODBC tracing via odbc.ini from which you can specify the file that the trace goes into. ALWAYS lets you control ODBC tracing via a directive, which is more convenient from within the SDE. ALWAYS generates the trace into MFSQLTRACE.LOG in the current directory, regardless of the settings in odbc.ini. Under normal development conditions, and depending on the project's build setting, this is the Debug or Release directory of the current project. NEVER means that the application will never be traced and overrides odbc.ini. As ODBC trace files can contain sensitive information, use NEVER in production applications in secure environments. Default is USER. For more information see the database driver documentation. | ||||||
[NO]PARAMARRAY | If PARAMARRAY is set, ODBC array binding is used, if it is supported by the ODBC driver, for all input parameters. Default is PARAMARRAY. | ||||||
[NO]PASS | The login to use to connect to the data source. This option works in conjunction with the INIT and/or CHECK options. | ||||||
[NO]QUALFIX | Causes the preprocessor to append three characters to the name of the host variables when declaring them to ODBC. Default is QUALFIX. | ||||||
[NO]RESULTARRAY | If RESULTARRAY is set, ODBC array binding is used, if it is supported by the ODBC driver, for all output parameters. Default is RESULTARRAY. | ||||||
STMTCACHE | Sets the cache size for prepared statements used by OpenESQL. The default is 20. Depending upon your application and data source, performance improvements or data errors can result if this value is set higher than that. | ||||||
[NO]TARGETDB=[ORACLEOCI |ORACLE7] | Set this directive if you want to optimize performance for a specific data source or have the application generate database calls using ORACLE OCI rather than ODBC calls. | ||||||
THREAD=[SHARE | ISOLATE] | Default is SHARE. If THREAD is set to ISOLATE, all connections, cursors and so on are local to the thread that creates them. This is required for multi-threaded application server environments such as IIS/ISAPI. With THREAD=SHARE, if you have a hard-coded CONNECT statement and thread 1 executes it and then thread 2 executes it, thread 2 gets an error because the connection is already open. With THREAD=ISOLATE, each thread gets its own connection. | ||||||
[NO]USECURLIB[NO | YES | IFNEEDED] | Controls use of the ODBC's Cursor Library. The Cursor Library can provide support for scrolling cursors when the underlying driver doesn't, and can also allow "simulated" positioned updates. With USECURLIB=YES, the Cursor Library will always be used. With USERCURLIB=NO, it will never be used. With the default USERCURLIB=IFNEEDED, it will be used if the application tries to do something the driver manager thinks the driver doesn't support. To use a scrolling cursor with the Cursor Library, you must use a STATIC cursor. To do positioned updates using the Cursor Library, you must use OPTCCVAL concurrency. Please beware, a "simulated" positioned update might hit more than one row. We recommend including the primary key in the select for this reason. |
If an error occurs when compiling a program that requires technical support, your support representative might ask you to provide additional debug files to help in determining the cause of the problem. You obtain these debug files by specifying extra SQL Compiler directives. You might want to specifiy some of these directives to help in your own debugging efforts. The directives are:
Directive |
File created |
Information within file |
---|---|---|
CHKECM(CTRACE) | ecmtrace.txt | This file contains pseudo COBOL code that shows the code generated to replace the EXEC SQL statements. This code is equivalent to output from the IBM DB2 COBOL precompiler. |
CHKECM(TRACE) | ecmtrace.txt | This file contains detailed information as to what information is passed between the DB2 ECM and the Compiler. If an error occurs that generates invalid syntax, this file will be needed to help isolate where the problem occurred. |
SQL(CTRACE) | sqltrace.txt | This file contains a detailed list of information passed to OpenESQL Precompiler Services, and the results. This file is very useful if an error might involve a bug in the OpenESQL system software as well as the OpenESQL ECM. |
ECMLIST | program-name.lst | This file is the standard COBOL list file, with pseudo COBOL code that shows the code generated to replace the EXEC SQL statements. You must also compile the program with the CHKECM(CTRACE) and LIST directives. |
Before your program can access any data in a database, it must make a connection to the database.
There are two methods your program can use to connect to a database.
The CONNECT statement is used typically if either of the following is true:
This is generally used if your program is only going to connect to one database which is known at compilation time. If you specify the INIT option of the SQL Compiler directive, the Compiler inserts a call at the start of the program. This call connects the program automatically to the data source specified in the DB option of the SQL Compiler directive and uses the login information specified in the PASS option.
When your application has finished working with a database, the application should disconnect from the database. This is done using the DISCONNECT statement.
If implicit connection is being used, OpenESQL automatically disconnects from the data source when the program terminates.
If you want OpenESQL to perform an implicit disconnect and rollback in the event of abnormal program termination, this can be achieved by specifying the INIT=PROT option of the SQL Compiler directive.
A number of keywords are recognized by OpenESQL and should not therefore be used within your program for other purposes. A full list of reserved keywords is given in the appendix Reserved Keywords.
To build an OpenESQL application, you need to:
The copy files sqlca.cpy and sqlda.cpy are provided in the directory $COBDIR/cpylib. You should ensure that this directory is included in the environment variable COBCPY.
A number of demonstration applications are supplied in the directory openesql, which is located in the directory demo under your Server Express base installation directory.
Before you can use any of the demonstration applications, you need to have installed at least one ODBC driver.
Some of the demonstration applications expect that a table called EMP exists on the database to which you are connecting.
The OpenESQL demonstration applications all produce a console log displaying their progress and, possibly, query results. They all terminate on receipt of an error, after displaying an error message.
The following programs are provided:
The file testconn.cbl is an OpenESQL demonstration program that shows how to use different formats of the CONNECT and DISCONNECT statements.
The file catalog.cbl is an OpenESQL demonstration program that shows how to use the ODBC catalog functions from COBOL.
The file static.cbl is an OpenESQL demonstration program that shows how to use basic SQL functions from COBOL. It demonstrates the use of INSERT, UPDATE, DELETE, SELECT INTO and SELECT using a cursor. It also shows the use of COMMIT and ROLLBACK.
The file dynquery.cbl is an OpenESQL demonstration program that shows how to use dynamic SQL functions from COBOL. It provides the capability for the user to enter any SQL statement and the program will execute them. It shows how to prepare a SQL statement and how to use the SQLDA structure to retrieve data from columns when the type of the column is not known when the program is compiled.
If you are accessing the EMP table described above, a sample query would be:
select FIRST_NAME, LAST_NAME, HIRE_DATE, SALARY from EMP
With OpenESQL, you can use the COMMIT and ROLLBACK statements to exploit the transaction control facilities of ODBC. Although ODBC specifies transaction AUTOCOMMIT after each statement as the default mode of operation, OpenESQL turns this off for greater compatibility with other SQL systems. If you require this functionality, specify the AUTOCOMMIT option of the SQL Compiler directive.
Note: Not all ODBC drivers implement transaction processing. Those that do not implement transaction processing may make immediate and permanent updates to the database. For more information see your database driver documentation.
The following table shows the mappings used by OpenESQL when converting between SQL and COBOL data types.
SQL Type |
COBOL Picture |
Notes |
SQL_CHAR(n) |
PIC X(n) |
|
SQL_VARCHAR(n) |
PIC X(n) |
|
SQL_LONGVARCHAR |
PIC X(max) | max = 64K |
SQL_DECIMAL(p,s) | PIC 9(p-s)V9(S) COMP-3 | p = precision (total number of digits). s = scale (number of digits after the decimal point). |
SQL_NUMERIC(p,s) | PIC 9(p-s)V9(S) COMP-3 | |
SQL_SMALLINT | PIC S9(4) COMP-5 | |
SQL_INTEGER | PIC S9(9) COMP-5 | |
SQL_REAL | COMP-2 | |
SQL_FLOAT | COMP-2 | |
SQL_DOUBLE | COMP-2 | |
SQL_BIT | PIC S9(4) COMP-5 | |
SQL_TINYINT | PIC S9(4) COMP-5 | |
SQL_BIGINT | PIC S9(18) COMP-3 | |
SQL_BINARY(n) | PIC X(n) | |
SQL_VARBINARY(n) | PIC X(n) | |
SQL_LONVARBINAR | PIC X(max) | |
SQL_DATE | PIC X(10) | yyyy-mm-dd |
SQL_TIME | PIC X(8) | hh:mm:ss |
SQL_TIMESTAMP | PIC X(29) | yyyy-mm-dd hh:mm:ss.ffffff |
The format of an ODBC date is yyyy-mm-dd, and an ODBC time is hh:mm:ss. These may not correspond to the native date/time formats for the data source in use. For input character host variables, native data source date/time formats can be used. For most data sources, we recommend a picture clause of PIC X(29), for example:
01 mydate PIC X(29). ... EXEC SQL INSERT INTO TABLE1 VALUES (1,'1997-01-24 12:24') END-EXEC ... EXEC SQL SELECT DT INTO :mydate FROM TABLE1 WHERE X = 1 END-EXEC DISPLAY mydate
Alternatively, you can use ODBC escape sequences. ODBC defines escape sequences for date, time and timestamp literals. These escape sequences are recognized by ODBC drivers which replace them with data source specific syntax.
The escape sequences for date, time and timestamp literals take the form:
{d 'yyyy-mm-dd'}
- for date. {t 'hh:mm:ss'}
- for time. {ts yyyy-mm-dd hh:mm:ss[.f...]
- for timestamp.
The example program below shows date, time and timestamp escape sequences being used:
working-storage section. EXEC SQL INCLUDE SQLCA END-EXEC 01 date-field1 pic x(29). 01 date-field2 pic x(29). 01 date-field3 pic x(29). procedure division. EXEC SQL CONNECT TO 'Server Express Sample1' USER 'admin' END-EXEC * If the Table is there drop it. EXEC SQL DROP TABLE DT END-EXEC * Create a table with columns for DATE, TIME and DATE and * TIME * NOTE: Access uses DATETIME column for all three. * Some databases will have dedicated column types. * If you are creating DATE/TIME columns on another data * source, refer to your database documentation to see how to * define the columns. EXEC SQL CREATE TABLE DT ( id INT, myDate DATE NULL, myTime TIME NULL, myTimestamp TIMESTAMP NULL) END-EXEC * INSERT into the table using the ODBC Escape sequences EXEC SQL INSERT into DT values (1 , {d '1961-10-08'}, *> Set just the date part {t '12:21:54' }, *> Set just the time part {ts '1966-01-24 08:21:56' } *> Set both parts ) END-EXEC * Retrieve the values we just inserted EXEC SQL SELECT myDate ,myTime ,myTimestamp INTO :date-field1 ,:date-field2 ,:date-field3 FROM DT where id = 1 END-EXEC * Display the results. display 'where the date part has been set :' date-field1 display 'where the time part has been set :' date-field2 display 'NOTE, most data sources will set a default' ' for the date part ' display 'where both parts has been set :' date-field3 * Remove the table. EXEC SQL DROP TABLE DT END-EXEC * Disconnect from the data source EXEC SQL DISCONNECT CURRENT END-EXEC stop run.
Alternatively you can use host variables defined with SQL TYPEs for date/time variables. Define the following host variables:
01 my-id pic s9(09) comp-5 01 my-date sql type is date 01 my-time sql type is time 01 my-timestamp sql-type is timestamp
and replace the INSERT statement with the following code:
* Insert into the table using SQL TYPE host variables MOVE 1 TO my-id MOVE "1961-10-08" TO my-date MOVE "12:21:54" TO my-time MOVE "1966-01-24 08:21:56" TO my-timestamp EXEC SQL INSERT into DT vlaue ( :my-id ,:my-date ,:my-time ,:my-timestamp ) END-EXEC
The SQLCA data structure is included in the file sqlca.cpy in the cpylib directory under your Server Express base installation directory. To include the SQLCA data structure in your program, use the following statement in the data division:
EXEC SQL INCLUDE SQLCA END-EXEC
If you do not include this statement, the COBOL Compiler automatically allocates an area, but it is not addressable from within your program. However, if you declare either of the data items SQLCODE or SQLSTATE separately, the COBOL Compiler generates code to copy the corresponding fields in the SQLCA to the user-defined fields after each EXEC SQL statement.
If you declare the data item MFSQLMESSAGETEXT, it is updated with a
description of the exception condition whenever SQLCODE is non-zero.
MFSQLMESSAGETEXT must be declared as a character data item, PIC X(n)
, where n
can be any legal value. This is particularly useful, as ODBC error
messages often exceed the 70-byte SQLCA message field.
Note: You do not need to declare SQLCA, SQLCODE, SQLSTATE or MFSQLMESSAGETEXT as host variables.
OpenESQL supports two statements that are used with stored procedures:
Provides generic support for ODBC stored procedure calls.
Provides backwards compatibility with the Micro Focus Embedded SQL Toolkit for Microsoft SQL Server.
A stored procedure can:
Note: The features provided by different database vendors vary considerably, and any given vendor will offer only a subset of the features listed above. For this reason, stored procedure calls are much less portable between data sources than other OpenESQL statements.
When a stored procedure is called, any parameters are passed as a comma separated list, optionally enclosed in parentheses. A parameter can be a host variable or a literal, or the keyword CURSOR. The keyword CURSOR causes the parameter to be unbound, and should only be used with Oracle 8 stored procedures which return result sets.
If the parameter is a host variable it can be followed by one of the following words, which indicate the parameter type: IN, INPUT, INOUT, OUT, OUTPUT. If no parameter type is specified, INPUT is assumed.
Host variable parameters can be passed as keyword parameters, by preceding the host variable with the formal parameter name and an equals sign:
EXEC SQL CALL myProc (keyWordParam = :hostVar) END-EXEC
For maximum portability:
If a stored procedure call returns a result set, it must be used in a cursor declaration, thus:
EXEC SQL DECLARE cursorName CURSOR FOR storedProcecureCall
The stored procedure is then called by OPENing the cursor and FETCHing result set rows, like any other type of cursor.
Currently OpenESQL supports only a single result set.
ODBC parameters differ from Oracle array parameters. The effect of using a parameter array is the same as repeating the statement for each element of the array. On a stored procedure call, if one parameter is passed as an array, then all parameters must be arrays with the same number of elements. The stored procedure will "see" one call for each "row" of parameters. The number of rows passed can be limited to less than the full array size by preceding the call with the phrase FOR :hvar where :hvar is an integer host variable containing a count of the number of rows to be passed.
ODBC supports positioned update, which updates the row most recently fetched by using a cursor. However, not all drivers provide support for positioned update.
Note: You cannot use host arrays with positioned update.
With some ODBC drivers, the select statement used by the cursor must contain a FOR UPDATE clause to enable positioned update. Most data sources require specific combinations of SCROLLOPTION and CONCURRENCY to be specified either by SET statements or in the DECLARE CURSOR statement. If this fails to work, the ODBC Cursor Library provides a restricted implementation of positioned update which can be enabled by compiling with the directive SQL(USECURLIB=YES) and using SCROLLOPTION STATIC and CONCURRENCY OPTCCVAL (or OPTIMISTIC). To avoid multiple rows being updated when using the ODBC Cursor Library, the cursor query should include the primary key column(s) for the table to be updated.
$SET SQL(usecurlib=yes) WORKING-STORAGE SECTION. EXEC SQL INCLUDE SQLCA END-EXEC *> after an sql error this has the full message text 01 MFSQLMESSAGETEXT PIC X(250). 01 IDX PIC X(04) COMP-5. EXEC SQL BEGIN DECLARE SECTION END-EXEC *> Put your host variables here if you need to port *> to other COBOL compilers EXEC SQL INCLUDE Products END-EXEC EXEC SQL END DECLARE SECTION END-EXEC PROCEDURE DIVISION. EXEC SQL WHENEVER SQLERROR perform OpenESQL-Error END-EXEC *> Demo for positioned updates using ACCESS datasource EXEC SQL CONNECT TO 'Inventory' USER 'admin' END-EXEC *> Put your program logic/SQL statements here EXEC SQL DECLARE CSR679 CURSOR FOR SELECT A.ProductID ,A.ProductName ,A.UnitPrice FROM Products A WHERE ( A.ProductID < 3 ) END-EXEC EXEC SQL SET SCROLLOPTION static END-EXEC EXEC SQL SET CONCURRENCY optccval END-EXEC EXEC SQL OPEN CSR679 END-EXEC PERFORM UNTIL SQLSTATE >= "02000" EXEC SQL FETCH CSR679 INTO :ProductID ,:ProductName:ProductName-NULL ,:UnitPrice:UnitPrice-NULL END-EXEC *> Process data from FETCH IF SQLSTATE = "00000" *> increase price by 10% compute unitprice = unitprice * 1.10 EXEC SQL UPDATE Products SET UnitPrice = :UnitPrice:UnitPrice-NULL WHERE CURRENT OF CSR679 END-EXEC END-IF END-PERFORM EXEC SQL CLOSE CSR679 END-EXEC EXEC SQL COMMIT END-EXEC EXEC SQL DISCONNECT CURRENT END-EXEC EXIT PROGRAM. STOP RUN. *> Default sql error routine / modify to stop program if needed OpenESQL-Error Section. display "SQL Error = " sqlstate " " sqlcode display MFSQLMESSAGETEXT *> stop run exit.
Some applications want to retrieve or store Unicode data in Microsoft SQL Server data sources without it being converted to ANSI. Previous versions of OpenESQL did not have a way of accessing data without it being automatically converted. Now, however, OpenESQL and Server Express can work directly with Unicode data without having it converted to ANSI, by using a new type of host variable. Microsoft SQL Server supports three Unicode column types:
To access these columns without the data being automatically converted, define a host variable with a definition of:
PIC N(xx) USAGE NATIONAL
where xx is the size of the column. This format is currently supported for both fixed and variable length data. Variable length data can be terminated with nulls to signify end of data for column when inserting or updating data. When data is retrieved from the data source, it will be space filled to the end of the host variable.
For example, the following program will retrieve employee information from the Northwind sample database that comes with Microsoft SQL Server 2000 product:
$SET UNICODE(NATIVE) $SET SQL WORKING-STORAGE SECTION. EXEC SQL INCLUDE SQLCA END-EXEC *> after an sql error this has the full message text 01 MFSQLMESSAGETEXT PIC X(250). 01 IDX PIC X(04) COMP-5. EXEC SQL BEGIN DECLARE SECTION END-EXEC *> Put your host variables here if you need to port *> to other COBOL compilers EXEC SQL INCLUDE Employees END-EXEC EXEC SQL END DECLARE SECTION END-EXEC PROCEDURE DIVISION. EXEC SQL WHENEVER SQLERROR perform OpenESQL-Error END-EXEC EXEC SQL CONNECT TO 'LocalServer' END-EXEC *> Put your program logic/SQL statements here EXEC SQL DECLARE CSR135 CURSOR FOR SELECT A.FirstName ,A.LastName ,A.EmployeeID ,A.HireDate FROM Employees A END-EXEC EXEC SQL OPEN CSR135 END-EXEC PERFORM UNTIL SQLSTATE >= "02000" EXEC SQL FETCH CSR135 INTO :Employees-FirstName ,:Employees-LastName ,:Employees-EmployeeID ,:Employees-HireDate:Employees-HireDate-NULL END-EXEC *> Process data from FETCH IF SQLSTATE < "02000" *> for array fetches, field sqlerrd(3) contains the number *> of rows returned *> PERFORM VARYING IDX FROM 1 BY 1 UNTIL IDX > SQLERRD(3) *> you will need to add code here to process the array *> END-PERFORM END-IF END-PERFORM EXEC SQL CLOSE CSR135 END-EXEC EXEC SQL DISCONNECT CURRENT END-EXEC EXIT PROGRAM. STOP RUN. *> Default sql error routine / modify to stop program if needed OpenESQL-Error Section. display "SQL Error = " sqlstate " " sqlcode display MFSQLMESSAGETEXT *> stop run exit.
This is the same code that would retrieve the data in ANSI except for the definitions in the INCLUDE copybook Employees which now looks like:
*> -------------------------------------------------------------- *> COBOL DECLARATION FOR TABLE Employees *> -------------------------------------------------------------- 01 DCLEmployees. 03 Employees-EmployeeID PIC S9(09) COMP-5. 03 Employees-LastName PIC N(20) USAGE NATIONAL. 03 Employees-FirstName PIC N(10) USAGE NATIONAL. 03 Employees-Title PIC N(30) USAGE NATIONAL. 03 Employees-TitleOfCourtesy PIC N(25) USAGE NATIONAL. 03 Employees-BirthDate PIC X(23). 03 Employees-HireDate PIC X(23). 03 Employees-Address PIC N(60) USAGE NATIONAL. 03 Employees-City PIC N(15) USAGE NATIONAL. 03 Employees-Region PIC N(15) USAGE NATIONAL. 03 Employees-PostalCode PIC N(10) USAGE NATIONAL. 03 Employees-Country PIC N(15) USAGE NATIONAL. 03 Employees-HomePhone PIC N(24) USAGE NATIONAL. 03 Employees-Extension PIC N(4) USAGE NATIONAL. 03 Employees-Photo PIC X(64000). 03 Employees-Notes PIC N(32000) USAGE NATIONAL. 03 Employees-ReportsTo PIC S9(09) COMP-5. 03 Employees-PhotoPath PIC N(255) USAGE NATIONAL.
Copyright © 2003 Micro Focus International Limited. All rights reserved.
This document and the proprietary marks and names
used herein are protected by international law.