Data Type Mapping

Overview of ODBC data types

ODBC defines certain generic data types, which every data source driver maps to its own internal types. Each driver needs to be queried about which types it supports, because different drivers support different types.

The types that Acu4GL for ODBC uses, if they exist in the driver, are:

For example, Informix maps these types like this:

SQL_CHAR CHAR
SQL_VARCHAR VARCHAR
SQL_DECIMAL DECIMAL or MONEY
SQL_NUMERIC no such type
SQL_SMALLINT SMALLINT
SQL_INTEGER INTEGER or SERIAL
SQL_REAL REAL
SQL_FLOAT no such type
SQL_DOUBLE FLOAT
SQL_TINYINT no such type
SQL_BIGINT no such type
SQL_BINARY no such type
SQL_VARBINARY no such type
SQL_LONGVARBINARY       BYTE
SQL_DATE DATE
SQL_TIMESTAMP DATETIME YEAR TO FRACTION(5)

Informix also defines a type that ODBC calls SQL_LONGVARCHAR, and Informix calls TEXT, which the Acu4GL for ODBC product doesn’t use.

Notice that Informix has two types that match the ODBC SQL_DECIMAL type, and two that match the SQL_INTEGER type. The Acu4GL product will usually use the first type that it finds that matches an ODBC type, unless there are restrictions on that type. For example, the SERIAL type is limited in that a table can have only one such column, while a typical table may have more than one column of integer data.

So the Acu4GL for ODBC product will use the Informix INTEGER type, instead of the SERIAL type for integer data.

For another example, MS Access maps these types like this:

SQL_CHAR CHAR
SQL_VARCHAR TEXT
SQL_DECIMAL no such type
SQL_NUMERIC CURRENCY
SQL_SMALLINT SHORT
SQL_INTEGER LONG or COUNTER
SQL_REAL SINGLE
SQL_FLOAT no such type
SQL_DOUBLE DOUBLE
SQL_TINYINT BYTE
SQL_BIGINT no such type
SQL_BINARY BINARY
SQL_VARBINARY VARBINARY
SQL_LONGVARBINARY       LONGBINARY
SQL_DATE no such type
SQL_TIMESTAMP DATETIME

Access also defines types, SQL_BIT = BIT and SQL_LONGVARCHAR = LONGTEXT which the Acu4GL for ODBC product doesn’t use.

Mapping COBOL data types to ODBC data types

When the Acu4GL for ODBC product creates a table, it uses what it determines to be the best match of a data type for any particular column.

This means that the database column will be able to hold any data that the COBOL data type can hold, and is as close as possible to the type of data that the COBOL program is using. This determination is based in part on what data types the data source has available. Obviously, if a data source doesn’t support some data type, the Acu4GL for ODBC product can’t use it with that data source. The actual algorithm used is rather complicated, but the general rules are as follows:

Occasionally, you may encounter a data source type that supports only type CHAR (which is the only data type that is guaranteed to exist, according to the ODBC specification). Under these data sources, all the COBOL data types will be mapped to CHAR types.

Mapping ODBC data types to COBOL data types

Sometimes developers are in a situation where they need to create a COBOL File Description based on an existing data source table. The most important thing to understand in this situation is that there is almost nothing that you can do wrong! When the Acu4GL product opens a data source table, the only thing it checks is that the column names match the COBOL data names.

When the Acu4GL product reads data from the data source, it essentially does a COBOL-style MOVE from the native data type to the COBOL data type, whatever it is. And since most types have a CHAR representation (in other words, you can actually display most data types, using a standard ODBC-capable tool), using PIC X(nn) for each column will work perfectly well.

A better general rule is to use a COBOL type that closely matches the data source data type, but don’t worry about getting an exact fit. So you can use PIC 9(9) whenever the data source has an INTEGER type.

If you have more information about the data source type, you might be able to use a different COBOL representation. For example, if you know that a particular column in an ODBC data source has values only in the range 0 – 999, you could use PIC 999 for your COBOL data. The COMP-type you use is really determined by your own preferences, and should have little bearing on the COBOL data type you choose.

If you want to somehow choose your COBOL data types so that there is a best fit, you can use the following mapping:

SQL_CHAR PIC X(nn)     nn =size of item
SQL_VARCHAR PIC X(nn)     nn = maximum size of item
SQL_DECIMAL PIC 9(n)v9(m)
SQL_NUMERIC PIC 9(n)v9(m)
SQL_SMALLINT PIC 9(5) COMP-5
SQL_INTEGER PIC 9(9) COMP-5
SQL_REAL USAGE FLOAT
SQL_FLOAT USAGE FLOAT
SQL_DOUBLE USAGE DOUBLE
SQL_TINYINT PIC 9(3) COMP-5
SQL_BIGINT PIC 9(9) COMP-5
SQL_BINARY PIC X(nn)
SQL_VARBINARY PIC X(nn)
SQL_LONGVARBINARY       PIC X(nn)
SQL_DATE PIC 9(6) or PIC 9(8)
SQL_TIMESTAMP USAGE DISPLAY
Note:

The BINARY data types are usually of a form that COBOL can’t understand anyway. You will usually just read these columns, and rewrite them unchanged. If you have more information about the data in the columns, you might be able to do something else, but this requires more knowledge about the columns.

The DECIMAL, NUMERIC, DATE, and TIMESTAMP types usually have special representations in a data source, which really doesn’t match any COBOL data type exactly. When the Acu4GL product binds the data (a technical term), it asks the data source to return it in character form, so the most efficient COBOL data type would probably be USAGE DISPLAY.