The original ODBC defines the C data types that are used by application variables and their corresponding type identifiers. These data types are used by the buffers bound to result set columns and statement parameters. For example, suppose an application wants to retrieve data from a result set column in character format. It declares a variable with the SQLCHAR* data type and binds this variable to the result set column with a type identifier of SQL_C_CHAR. ODBC also defines a default mapping from each SQL data type to a C data type. For example, a 2-byte integer in the data source is mapped to a 2-byte integer in the application. To use the default mapping, an application specifies the SQL_C_DEFAULT type identifier. However, use of this identifier is discouraged for interoperability reasons.
Fortran and C data types do not always have a direct correspondence relationship. For example, unsigned integers do not exist in Fortran. f90SQL has mapped all ODBC-defined C data types into the Fortran types that match them more closely. Although f90SQL allows the use of C data type identifiers, as a general rule you should not use them in your applications to avoid conflicts and mistakes, which may be very difficult to track. Fortran data types are identified in the same fashion that ODBC C data types, but instead of the letter C, they use the letter F. For example, the C type identifier for short signed integers is SQL_C_SSHORT. The type identifier for the corresponding data type in Fortran is SQL_F_SSHORT.
C has a richer data-type set than Fortran does. In C integers can be declared as signed or unsigned. Most Fortran compilers do not allow for this distinction. Because of this, many Fortran ODBC data types map to the same Fortran data type. For example, SQL_F_SSHORT and SQL_F_USHORT, map to the same Fortran type (usually integer*2).
When declaring variables, Fortran programs should used the kinds provided by f90SQL. A kind indicates to the Fortran compiler the number of bytes a given Fortran data type will use. For example, the following declaration tells the compiler that variable i is a 2-byte integer:
integer(kind=2)::i
The ODBC Fortran type identifier for variable i would be SQL_F_SSHORT. f90SQL defines kind-values using named-constants, which make it easier to relate the declaration of variables to their corresponding data type identifier. For example, instead of declaring i as previously showed, you can use the following declaration:
integer(SQLSMALLINT_KIND)::i
You do not have to worry about how many bytes variable i has. You know it is a small signed integer, and as such, it can be identified to ODBC using the identifier SQL_F_SSHORT.
The following table shows the f90SQL data types, their identifiers, and Fortran type they represent. It also includes the corresponding C identifiers for reference.
Table 4.3. ODBC Fortran data type identifiers
| f90SQL type identifier | f90SQL declaration | Fortran type |
| SQL_F_CHAR | character(len=*) | character(len=*) |
| SQL_F_SSHORT [j] | integer (SQLSMALLINT_KIND) | integer(kind=2) |
| SQL_F_USHORT [j] | integer (SQLUSMALLINT_KIND) | integer(kind=2) |
| SQL_F_SLONG [j] | integer (SQLINTEGER_KIND) | integer(kind=4) |
| SQL_F_ULONG [j] | integer (SQLUINTEGER_KIND) | integer(kind=4) |
| SQL_F_FLOAT | real(SQLREAL_KIND) | real(kind=4) |
| SQL_F_DOUBLE | real(SQLDOUBLE_KIND), real(SQLFLOAT_KIND) |
real(kind=8) |
| SQL_F_BIT | integer (SQLCHAR_KIND) | integer(kind=1) |
| SQL_F_STINYINT [j] | integer (SQLCHAR _KIND) | integer(kind=1) |
| SQL_F_UTINYINT [j] | integer (SQLCHAR _KIND) | integer(kind=1) |
| SQL_F_SBIGINT | integer (SQLBIGINT _KIND) | integer(kind=8) [h] |
| SQL_F_UBIGINT | integer (SQLUBIGINT _KIND) | integer(kind=8) [h] |
| SQL_F_BINARY | integer (SQLPOINTER_KIND) [l] | integer(kind=4) [l] |
| SQL_F_BOOKMARK [i] | integer (BOOKMARK_KIND) | integer(kind=4) [d] |
| SQL_F_VAR_BOOKMARK | character(len=*) [l] |
character(len=*) [l] |
| SQL_F_TYPE_DATE [c] | type(SQL_DATE_STRUCT) |
|
| SQL_F_TYPE_TIME [c] | type(SQL_TIME_STRUCT) |
|
| SQL_F_TYPE_TIMESTAMP [c] | type(SQL_TIMESTAMP_STRUCT) |
|
| SQL_F_NUMERIC | type(SQL_NUMERIC_STRUCT) |
|
| SQL_F_GUID | type(SQLGUID) |
|
| All Fortran interval data types | type(SQL_INTERVAL_STRUCT) | See interval data types in Appendix 4 |
Table 4.3 (continuation)
| f90SQL type identifier | C type identifier | ODBC C typedef | C type |
| SQL_F_CHAR | SQL_C_CHAR | SQLCHAR * | unsigned char * |
| SQL_F_SSHORT [j] | SQL_C_SSHORT [j] | SQLSMALLINT | short int |
| SQL_F_USHORT [j] | SQL_C_USHORT [j] | SQLUSMALLINT | unsigned short int |
| SQL_F_SLONG [j] | SQL_C_SLONG [j] | SQLINTEGER | long int |
| SQL_F_ULONG [j] | SQL_C_ULONG [j] | SQLUINTEGER | unsigned long int |
| SQL_F_FLOAT | SQL_C_FLOAT | SQLREAL | float |
| SQL_F_DOUBLE | SQL_C_DOUBLE | SQLDOUBLE, SQLFLOAT |
double |
| SQL_F_BIT | SQL_C_BIT | SQLCHAR | unsigned char |
| SQL_F_STINYINT [j] | SQL_C_STINYINT [j] | SQLSCHAR | signed char |
| SQL_F_UTINYINT [j] | SQL_C_UTINYINT [j] | SQLCHAR | unsigned char |
| SQL_F_SBIGINT | SQL_C_SBIGINT | SQLBIGINT | _int64 [h] |
| SQL_F_UBIGINT | SQL_C_UBIGINT | SQLUBIGINT | unsigned _int64 [h] |
| SQL_F_BINARY | SQL_C_BINARY | SQLCHAR * | unsigned char * |
| SQL_F_BOOKMARK [i] | SQL_C_BOOKMARK [i] | BOOKMARK | unsigned long int [d] |
| SQL_F_VAR_BOOKMARK | SQL_C_VAR_BOOKMARK | SQLCHAR * | unsigned char * |
| SQL_F_TYPE_DATE [c] | SQL_C_TYPE_DATE [c] | SQL_DATE_STRUCT |
|
| SQL_F_TYPE_TIME [c] | SQL_C_TYPE_TIME [c] | SQL_TIME_STRUCT |
|
| SQL_F_TYPE_TIMESTAMP [c] | SQL_C_TYPE_TIMESTAMP [c] | SQL_TIMESTAMP_STRUCT |
|
| SQL_F_NUMERIC | SQL_C_NUMERIC | SQL_NUMERIC_STRUCT |
|
| SQL_F_GUID | SQL_C_GUID | SQLGUID |
|
[a] The values of the year, month, day, hour, minute, and second fields
in the datetime C data types must conform to the constraints of the Gregorian calendar.
[b] The value of the fraction field is the number of billionths of a second and ranges
from 0 to 999,999,999 (1 less than 1 billion). For example, the value of the fraction
field for a half-second is 500,000,000. For a thousandth of a second (one millisecond) it
is 1,000,000. For a millionth of a second (one microsecond) it is 1,000, and for a
billionth of a second (one nanosecond) it is 1.
[c] In ODBC 2.x, the C date, time, and timestamp data types are SQL_C_DATE, SQL_C_TIME,
and SQL_C_TIMESTAMP.
[d] ODBC 3.5 applications should use SQL_C_VARBOOKMARK, not SQL_C_BOOKMARK. When an ODBC
3.5 application works with an ODBC 2.x driver, the ODBC 3.5 Driver Manager will map
SQL_C_VARBOOKMARK to SQL_C_BOOKMARK.
[e] A number is stored in the val (or value for f90SQL) field
of the SQL_NUMERIC_STRUCT structure as a scaled integer, in little endian mode (the
leftmost byte being the least-significant byte). For example, the number 10.001 base 10,
with a scale of 4, is scaled to an integer of 100010. Because this is 186AA in hexadecimal
format, the value in SQL_NUMERIC_STRUCT would be "AA 86 01 00 00
00",
with the number of bytes defined by the SQL_MAX_NUMERIC_LEN.
[f] The precision and scale fields of the SQL_C_NUMERIC or SQL_F_NUMERIC data type are
never used for input from an application, only for output from the driver to the
application. When the driver writes a numeric value into the SQL_NUMERIC_STRUCT, it will
use its own driver-specific default as the value for the precision field. It will also use
the value in the SQL_DESC_SCALE field of the application descriptor (which defaults to 0)
for the scale field. An application can provide its own values for precision and scale by
setting the SQL_DESC_PRECISION and SQL_DESC_SCALE fields of the application descriptor.
[g] The sign field is 1 if positive, 0 if negative.
[h]_int64 or int(kind=8) may not be supplied by some compilers.
[i] _SQL_C_BOOKMARK has been deprecated in ODBC 3.x.
[j] _SQL_C_SHORT, SQL_C_LONG, and SQL_C_TINYINT have been replaced in ODBC by signed and
unsigned types: SQL_C_SSHORT and SQL_C_USHORT, SQL_C_SLONG and SQL_C_ULONG, and
SQL_C_STINYINT and SQL_C_UTINYINT.
[k] SQL_C_GUID may only be converted to SQL_CHAR or SQL_WCHAR.
[l] SQL_F_VAR_BOOKMARK and SQL_F_BINARY are defined as pointers to arrays of type
SQLCHAR_KIND.