Chapter 6: Working with COBOL

After the environment has been set up for the Database Connectors™ interface, you are ready to use the system. This chapter describes how to prepare your COBOL program and compile it for use with Database Connectors.

Preparing and Compiling Your COBOL Program, an Example

The following example illustrates how to set up a COBOL program to use Database Connectors' relational database management system (RDBMS).

Note: If you are not familiar with eXtended File Descriptor (XFD) directives, you may want to read the chapter Using XFD Directives before continuing with this section.

The purchase orders file from a COBOL program at an imaginary company will be stored in the database. This file contains the records that handle all of the information from the company's purchase orders.

Within the purchase orders file are two record types:

The file is keyed off the purchase order number. We will build and examine the database table three times, to illustrate three different approaches to using the COBOL file descriptor:

Here's the sample code:

IDENTIFICATION DIVISION.
program-id.  purchase.
ENVIRONMENT DIVISION.
input-output section.
file-control.
 
select p-o-file
assign to disk "purch1"
organization is indexed 
access mode is dynamic
record key is p-o-number
file status is p-o-status.
 
DATA DIVISION.
file section.
fd p-o-file.
01 p-o-record.
   03 p-o-division-number                pic 9(3).
   03 p-o-record-type                    pic x.
      88 header-record                   value "h".
      88 detail-record                   value "d".
   03 p-o-number                         pic 9(10).
   03 p-o-number-detail redefines 
         p-o-number.
      05 picking-ticket-number           pic 9(6).
      05 shipping-region                 pic 9(2).
      05 p-o-customer-type               pic 9(2).
      05 p-o-customer-breakdown redefines 
            p-o-customer-type.
         07 customer-category            pic x.
         88 p-o-customer-retail          value "r".
         88 p-o-customer-whlsale         value "w".
         07 customer-pay-format          pic x.
            88 is-net-30                 value "3".
            88 is-net-10                 value "1". 
   03 p-o-date.
      05 p-o-yy                          pic 9(2).
      05 p-o-mm                          pic 9(2).
      05 p-o-dd                          pic 9(2).
 
01 p-o-detail-record.
   03 p-o-dept-number                    pic 9(3).
   03 p-o-record-type                    pic x.
   03 detail-p-o-number                  pic 9(10).
   03 p-o-shipping-info.
      05 p-o-quantity-to-ship            pic s9(4) comp.
      05 p-o-total-quantity              pic s9(4) comp.
   03 p-o-notes.
      05 notes-line occurs 3 times       pic x(40).
working-storage section.
01 p-o-status                            pic x(2).
PROCEDURE DIVISION.
level-1 section.
main-logic.
 
open output p-o-file.
close p-o-file.
stop run.
Related Topic:

Using XFD Directives

Compiling with just the CREATEXFD Directive

You can compile the preceding program with just the CREATEXFD directive to generate the XFD. The compiled program will run and will build the database table shown at the end of this section.

Here's how the database table is built. First, any fields listed in the KEY IS clause of the SELECT are included ("p-o-number" in this example). Then the Compiler takes the largest record ("p-o-detail-record") and lists the fields that make up that record. The rest of this section shows the specific fields that are placed into the table.

All of the data from the COBOL program is stored in and retrieved from the database, even though not all fields are explicitly named in the database table. For a description of how this works, see the chapter XFDs.

The underlined fields are the only ones that will be entered into the table:

fd p-o-file.
 01  p-o-record.
     03  p-o-division-number                   pic 9(3).
     03  p-o-record-type                       pic x.
         88  header-record                     value "h".
         88  detail-record                     value "d".
     03  p-o-number                            pic 9(10).
     03  p-o-number-detail redefines p-o-number.
         05  picking-ticket-number             pic 9(6).
         05  shipping-region                   pic 9(2).
         05  p-o-customer-type                 pic 9(2).
         05  p-o-customer-breakdown redefines 
               p-o-customer-type.
             07  customer-category             pic x.
                 88  p-o-customer-retail       value "r".
                 88  p-o-customer-whlsale      value "w".
             07  customer-pay-format           pic x.
                 88 is-net-30                  value "3".
                 88 is-net-10                  value "1".
     03  p-o-date.
         05  p-o-yy                            pic 9(2).
         05  p-o-mm                            pic 9(2).
         05  p-o-dd                            pic 9(2).
 
 01  p-o-detail-record.
     03  p-o-dept-number                       pic 9(3).
     03  p-o-record-type                       pic x.
     03  detail-p-o-number                     pic 9(10).
     03  p-o-shipping-info.
         05  p-o-quantity-to-ship              pic s9(4) comp.
         05  p-o-total-quantity                pic s9(4) comp.
     03  p-o-notes.
         05  notes-line occurs 3 times         pic x(40).

As the table is built:

Note: "detail-p-o-number" is not part of the table because the key overlays this area.

The following table is built in the database:

Column Name Type
p_o_number number(10)1
p_o_dept_number number(3) 1
p_o_record_type char(1)
p_o_quantity_to_ship      number(4) 1
p_o_total_quantity number(4) 1
notes_line_1 char(40)
notes_line_2 char(40)
notes_line_3 char(40)

Footnotes:

1.

The actual database datatype may vary.

For a list of supported data types and their COBOL equivalents, see the Limits and Ranges section found in the appendix of this manual that is specific to your RDBMS.

Related Topics

Compiling with the WHEN XFD Directive

Suppose that you wanted both record formats to be placed into the table. This might be the case if you intended to do any work within your RDBMS. Add the WHEN XFD directive in front of each record, as shown below. The underlined fields are the ones that will be entered into the table:

fd p-o-file.
*(( xfd when p-o-record-type = "h" ))
 01  p-o-record.
     03  p-o-division-number                       pic 9(3).
     03  p-o-record-type                           pic x.
         88  header-record                         value "h".
         88  detail-record                         value "d".
     03  p-o-number                                pic 9(10).
     03  p-o-number-detail redefines p-o-number.
         05  picking-ticket-number                 pic 9(6).
         05  shipping-region                       pic 9(2).
         05  p-o-customer-type                     pic 9(2).
         05  p-o-customer-breakdown redefines 
               p-o-customer-type.
             07  customer-category                 pic x.
                 88  p-o-customer-retail           value "r".
                 88  p-o-customer-whlsale          value "w".
             07  customer-pay-format               pic x.
                 88  is-net-30                     value "3".
                 88  is-net-10                     value "1".
     03  p-o-date.
         05  p-o-yy                                pic 9(2).
         05  p-o-mm                                pic 9(2).
         05  p-o-dd                                pic 9(2).
*(( xfd when p-o-record-type = "d" ))
 01  p-o-detail-record.
     03  p-o-dept-number                           pic 9(3).
     03  p-o-record-type                           pic x.
     03  detail-p-o-number                         pic 9(10).
     03  p-o-shipping-info.
         05  p-o-quantity-to-ship                  pic s9(4) comp.
         05  p-o-total-quantity                    pic s9(4) comp.
     03  p-o-notes.
         05  notes-line occurs 3 times             pic x(40).

Note: "p-o-record-type" is entered into the table only once. The "detail-p-o-number" field is not part of the table, because the key overlays this area.

The following table is built in the database:

Column Name Type
p_o_division_number number(3) 5
p_o_record_type char(1)
p_o_number number(10) 5
p_o_yy number(2) 5
p_o_mm number(2) 5
p_o_dd number(2) 5
p_o_dept_number number(3) 5
p_o_quantity_to_ship      number(4) 5
p_o_total_quantity number(4)
notes_line_1 char(40)
notes_line_2 char(40)
notes_line_3 char(40)
Related Topic:

WHEN XFD directive

Using Additional XFD Directives

In this final approach, you decide to streamline the code a bit, so you introduce the following three changes:

fd p-o-file.
$xfd when p-o-record-type = "h"
 01  p-o-record.
     03  p-o-division-number                      pic 9(3).
     03  p-o-record-type                          pic x.
         88  header-record                        value "h".
         88  detail-record                        value "d".
     03  p-o-number                               pic 9(10).
     03  p-o-number-detail redefines p-o-number.
         05  picking-ticket-number                pic 9(6).
         05  shipping-region                      pic 9(2).
         05  p-o-customer-type                    pic 9(2).
         05  p-o-customer-breakdown redefines 
               p-o-customer-type.
             07  customer-category                pic x.
                 88  p-o-customer-retail          value "r".
                 88  p-o-customer-whlsale         value "w".
             07  customer-pay-format              pic x.
                 88  is-net-30                    value "3".
                 88  is-net-10                    value "1".
$xfd use group, date
     03  p-o-date.
         05  p-o-yy                               pic 9(2).
         05  p-o-mm                               pic 9(2).
         05  p-o-dd                               pic 9(2).
$xfd when p-o-record-type = "d"
 01  p-o-detail-record.
     03  p-o-dept-number                          pic 9(3).
     03  p-o-record-type                          pic x.
     03  detail-p-o-number                        pic 9(10).
     03  p-o-shipping-info.
         05  p-o-quantity-to-ship                 pic s9(4) comp.
         05  p-o-total-quantity                   pic s9(4) comp.
$xfd use group, name = notes
     03  p-o-notes.
         05  notes-line occurs 3 times            pic x(40).

Note: "p-o-record-type" is entered only once into the table. The "detail-p-o-number" field is not part of the table, because the key overlays this area.

The following table is built in the database:

Column Name Type
p_o_division_number      number(3)
p_o_record_type char(1)
p_o_number number(10)
p_o_date date
p_o_dept_number number(3)
p_o_quantity_to_sh number(4)
p_o_total_quantity number(4)
notes char(120)

Related Topics

Creating a COBOL Application

Database Connectors is designed to simplify the process of working with relational databases as much as possible for the COBOL application developer. With this in mind, we allow you to use the traditional COBOL “OPEN OUTPUT” verb to create a new database table.

In this section, we will use a sample COBOL program that comes with reUZE Developer to create a new database table in which to store our COBOL information. In this section, you will:

Creating a Visual Studio Solution

In this section, we will create a Visual Studio solution for our COBOL application. We will then use the checker to compile the COBOL application to generate an “eXtended File Descriptor” (XFD) that will be used to map your data from the record-oriented COBOL application to a relational database’s column-oriented format.

  1. In Visual Studio, click File > New > Project > COBOL Projects > Native > Console Applications.

    The new project will generate a template program called program1.cbl that is not needed. You may want to delete it.

  2. Create a new project called dbsample in a directory of your choice.
  3. In the Solution Explorer window, double-click in Properties and be sure that you have the following in the Application, COBOL, and Debug tabs:
    Application Tab     Output type: Console Application
    COBOL TabNative

    COBOL dialect: Non-mainframe

    Link settings

    • Runtime Library
      • [x] Shared
    • Thread Model
      • [x] Multi-threaded
    • Linker Parameters
      • Link with objs: "C:\Program Files\Micro Focus\ reUZE Developer 6.0\Base\Lib\FHRSUB.OBJ"
      • [x] Include system programs

        If you don't check this, you don't need to link with fhrsub.obj

    Debug TabStart Options
    • Working directory: <location of xfd file> (for example, c:\myproject\xfd).
  4. In the Solution Explorer window, right-click in the dbsample project name.
  5. Click Add > Existing Item.
  6. Browse to the reUZE Developer subdirectory Examples\Database Connectors and add the sample program order1.cbl.
  7. Open the order1.cbl program.

    Notice that to instruct to the checker to generate the XFD file, we use at the beginning of the COBOL program the following directive:

    $SET CREATEXFD

    If you want the XFD files to be placed in a different directory than the current one, you can use the following format:

    $SET CREATEXFD(XFD-DIRECTORY=c:\myproject\xfd)

    This directive can also be set using the project’s properties. To do this, double-click on the project’s Properties, click on the COBOL tab, and in the Additional Directives entry field type CREATEXFD. Save the changes.

  8. Build your project.

    The checker will create the purch1.xfd file in your current XFD directory.

Setting the Run-time Environment Variable

After you have built your project, you need to set the environment variables to point to your ACUFH configuration file and to enable the dynamic redirection of the file handler. In this example, we will use a project directory of C:\DataConnectors\Test and a configuration file of mssql.cfg, meaning that we are using Microsoft SQL Server for this exercise. To do this, follow the steps below:

  1. Close your Solution and exit Visual Studio.
  2. Open a Visual Studio command prompt and set the following variables:
    Variable     Value
    A_CONFIG c:\DataConnectors\Test\mssql.cfg
    DYNREDIR DYNCONFIG:EXPAND
    FHREDIRc:\DataConnectors\Test\fhredir.cfg

Turning on Tracing

To aid in resolving any difficulties that we may encounter in the initial configuration of Database Connectors, we will also set some variables that will allow us to perform tracing. After successful configuration of Database Connectors, you will want to turn tracing off, because it can result in a significant performance penalty.

Set the new variable:

VariableValue
MFTRACE_CONFIG      c:\DataConnectors\Test\config.ctf

In addition, you should create a configuration file for the tracing configuration. The following is a potential example of the file c:\DataConnectors\Test\config.ctf:

mftrace.emitter.textfile#Format   = $(TIME) $(THREAD) $(COMPONENT) $(EVENT) $(LEVEL) :$(DATA)
mftrace.level.mf.rts           	  = debug
mftrace.level                    	= info
mftrace.comp.mf.rts#pgm       	   = true
mftrace.comp.mf.rts#pgmload      	= true
mftrace.comp.mf.rts#syspgm     	  = true
mftrace.comp.mf.rts#eprintf    	  = 1
mftrace.emitter.TEXTFILE#location	= C:\DataConnectors\Test\logs

You will also need to create the directory C:\DataConnectors\Test\logs to receive your log files.

Running the Sample Program

When you have completed the steps for creating your configuration file and preparing your environment, you are ready to create the new database table. Start Visual Studio from the Visual Studio 2008 command prompt using the devenv command.

Run your application in Visual Studio and step through the code. Upon successful creation, a new table will have been created in the database.

Errors You May Encounter

When you come to the line “open output p-o-file”, you may receive a "File Error:9k". If you check the log files that were created in the directory pointed to by mftrace.emitter.TEXTFILE#location = C:\DataConnectors\Test\logs, you will see the following:

init_connection
Trying to open a connection to server MyBadServer
report_status called from 1176
[1] 08001 17 – [DBNETLIB]SQL Server does not exist or access denied.
[2] 01000 53 – [DBNETLIB]ConnectionOpen (Connect()).

where MyBadServer is the value set in your configuration file for A-MSSQL-DEFAULT-CONNECTION.

Checking the Resulting Database Table

Once the COBOL application has finished, you will want to review the resulting database table to ensure that it has the desired format and column names. In this exercise we are using Microsoft SQL Server.

  1. To review the structure of the table, bring up Microsoft’s SQL Server Management Studio.
  2. Connect to the data source you used in your configuration file. The entries map as follows:
    Server Management Studio      Database Connectors
    Server nameA-MSSQL-DEFAULT-CONNECTION
    LoginA-MSSQL-LOGIN
    PasswordA-MSSQL-PASSWD
  3. Once you are connected, perform the following steps:
    1. Expand the “Databases” folder.
    2. Expand the folder referred to in the A-MSSQL-DATABASE setting from your configuration file.
    3. Expand the “Tables” folder.
    4. Locate and expand the folder containing the name "purch1."

      Once you have expanded this folder you will see that it contains a list of subfolders that describe the columns that comprise the table, as well as the indexes on the table. (Note that there is also a folder titled “Keys.” This should not be confused with the “Indexes,” which is where the equivalent of the COBOL keys will be created.)

      Indexes names will take the form I<tablename><key>.

    You will want to review the objects in the “Columns” folder for readability and to ensure that the COBOL fields you wanted to be included were indeed created. You can affect field names with the use of the NAME directive placed in your COBOL FD. You can modify the table structure with the USE GROUP, WHEN, and other directives placed within your COBOL FD.


Copyright © 2009 Micro Focus (IP) Ltd. All rights reserved.